Java,如何找出哪个类或方法使用了大量内存?

问题描述 投票:0回答:3

这是我的Java项目的一日内存曲线。我如何找出哪个类或方法使用了大量内存?

java jvm
3个回答
3
投票

您需要一个可以执行 JVM 分配分析的工具。

Java Flight Recorder (JFR) 可以帮助您进行低开销分配分析(12 - 旧版本的文档,UI 现在看起来完全不同,但“分配”和“TLAB”仍然是用于找东西)。确保在您使用的设置中分配分析已启用。在 OpenJDK 11 之前,这是一个商业功能。他们说现在其他一些工具也可以以较低的开销实现这一点(例如 async-profiler)。

如果您不关心应用程序变得慢得无法使用并且使用 JDK < 11(?), VisualVM used to be able to show you stack traces of allocations. I can't find it in the latest version (1.4.2 as of now), but can find it in JVisualVM shipped with my Oracle JDK 8-something. "Profiler" >,请检查“设置”>“内存设置”> 检查“记录分配堆栈跟踪”。开始分析,等待,等待,等待,确定最大的分配,右键单击“拍摄快照并显示分配堆栈跟踪”。看起来 YourKit 基本上是一样的,还有 JProfiler(他们称之为“分配记录”)。再次强调:会大大减慢应用程序的速度,所以不要在产品中使用它。


1
投票

您定期进行堆转储并使用 MAT-内存分析器工具 (https://www.eclipse.org/mat/) 等工具进行分析。该工具提供了哪个对象/类占用更多内存以及从哪个线程创建等。

如何查找特定对象是从哪个线程创建的?

  1. 在 MAT 中,单击直方图 - 它将显示转储中可用的类列表。为了演示,让我仅过滤掉班级
    java.lang.String

  1. 右键单击任何类名,在弹出窗口中选择List Objects ---> with Outgoing References

  1. 上面的步骤列出了所选类的所有实例。右键单击任意一个类名,然后从弹出窗口中选择 Merge Shortest Paths to GC Roots ---> with allreferences

  1. 完成上述步骤后,您可以查看从哪个Thread类特定对象被创建。


0
投票

如果你只想要堆,你可以运行

jmap -histo:live <YOUR PID>
并解析(相当简洁)的输出。

参考

© www.soinside.com 2019 - 2024. All rights reserved.