【问题标题】:Java,How do I find out which class or method USES a lot of memory?Java,如何找出哪个类或方法占用大量内存?
【发布时间】:2019-06-10 02:01:28
【问题描述】:

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

【问题讨论】:

  • 谢谢,我知道这个工具,但是我的主管想知道哪些方法在某个时间会占用大量内存,哪些方法会在堆中生成大量对象.
  • 例如,哪个方法产生这个String对象
  • 您如何收集图表中显示的数据?来源很重要。
  • 我在这个项目中使用了JavaMelody,但不是每个项目都使用它,所以我想找到一个通用的方式我在这个项目中使用了JavaMelody,

标签: java jvm


【解决方案1】:

你需要一个可以做JVM allocation profiling的工具。

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

如果您不关心您的应用程序变得异常缓慢并且在 JDK 检查“设置”>“内存设置”>检查“记录分配堆栈跟踪”。开始分析,等待,等待,等待,确定最大的分配,右键单击,“拍摄快照并显示分配堆栈跟踪”。它看起来像 YourKit does basically the same,以及 JProfiler(他们称之为“分配记录”)。再说一遍:会大大降低应用程序的速度,所以不要在 prod 中使用它。

【讨论】:

    【解决方案2】:

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

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

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

    1. 右键单击任何类名,在弹出窗口中选择 List Objects ---> 带有传出引用

    1. Above Step 列出所选类的所有实例。右键单击任何一个类名,然后从弹出窗口中选择 Merge Shortest Paths to GC Roots ---> with all references

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

    【讨论】:

    • "以及它是从哪个线程创建的" -- 上次检查时,我在堆转储中找不到此信息,您能否给个提示在哪里看?
    • @starikoff ,更新了“它是从哪个线程创建的”的答案。
    • 感谢您的详尽评论和您的努力!我认为尽管您看到的事情有些错误:这个线程是在转储时对对象的引用(这有点像“GC 根”的定义)。此时并非所有对象都将 Thread 作为 GC 根;实际上很可能不会,请查看您的一些(非 JVM)类作为示例。
    猜你喜欢
    • 2018-06-07
    • 2022-10-30
    • 2020-04-28
    • 2011-05-11
    • 2016-03-10
    • 1970-01-01
    • 2013-11-16
    • 2014-05-11
    相关资源
    最近更新 更多