当线程无法访问所有已用堆时查找 Java 内存泄漏

2024-04-29

我正在研究基于 Java 的大型系统中潜在的内存泄漏(或至少是内存浪费)。 JVM 运行时的最大堆大小为 5 GB,2-3GB 堆使用量是应用程序的预期基准。 (可能会有更高的峰值)

在我正在调查的过载场景中,堆被填满。使用“Eclipse MemoryAnalyzer Tool”分析堆转储显示(毫不奇怪)堆已完全用完。

MAT 显示了 2 个潜在的泄漏候选者,两者都大约保留了 2.5GB:java.lang.Thread 和系统中在系统事务处理期间广泛使用的域对象。然而,所有这些域对象(毫不奇怪)都可以从 Thread 实例访问。毕竟,这些线程正在处理事务。因此,java.lang.Thread 的 2.5 GB 几乎完全是由这些域对象造成的。这里并不奇怪。

列出所有 java.lang.Thread 实例的对象树并对所有线程的保留堆进行求和,得到 2.5 GB 的保留堆。

如果无法从 java.lang.Thread 实例访问它们,我应该在哪里查找填充堆所需的其他 2.5 GB 空间? - 终结器队列中没有任何内容 - 没有大量无法到达的对象等待 GC

我认为提出这个问题的另一种方法是:“如何找到从 java.lang.Thread 实例无法访问的所有对象?也许是 OQL 查询?”另一个问题是:“有哪些类型的对象除了 Finalizer 队列中的对象和挂起 GC 的未引用对象之外,无法从 java.lang.Thread 的实例访问?”


我也遇到了我们网站内存泄漏的问题,
Use yourkit java 分析器 http://www.yourkit.com/java/profiler/index.jsp它提供了大量的信息,并且凭借其能力,您可以在所有内存都被利用的情况下获得更广泛的图像。
你可以找到很棒的教程查找 Java 内存泄漏 http://www.yourkit.com/docs/demo/JavaMemoryLeak/JavaMemoryLeak.htm用上面的工具。

你的问题,

“除了 Finalizer 队列中的对象和挂起 GC 的未引用对象之外,还有哪些类型的对象无法从 java.lang.Thread 实例访问?”

有四种对象,

  1. 强可达性,可以通过活动对象的引用直接到达的对象
  2. 弱/软可达,具有与之关联的弱/软引用的对象
  3. Pending Finalization,等待终结的对象,并且可以通过终结器队列访问其引用
  4. Unreachable 这些是从 GC root 无法访问但尚未收集的对象

除此之外,JVM还使用本机内存,您可以在IBM上找到其信息JVM 使用的堆和本机内存 http://publib.boulder.ibm.com/infocenter/javasdk/v1r4m2/index.jsp?topic=%2Fcom.ibm.java.doc.diagnostics.142j9%2Fhtml%2Fheapandnativememusejvm.html and 谢谢你的记忆 http://www.ibm.com/developerworks/library/j-nativememory-linux/根据 YourKit 的JVM内存结构 http://www.yourkit.com/docs/kb/sizes.jsp具有非堆内存,其定义为

另外,JVM 还有堆以外的内存,称为非堆内存。它在 JVM 启动时创建,存储每个类的结构,例如运行时常量池、字段和方法数据、方法和构造函数的代码以及内部字符串。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当线程无法访问所有已用堆时查找 Java 内存泄漏 的相关文章

随机推荐