java - 当线程无法访问所有使用的堆时发现 Java 内存泄漏

标签 java debugging memory-leaks

我正在调查大型 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 查询?另一个问题:“什么样的对象除了终结器队列中的对象和等待 GC 的未引用对象之外,还有哪些 java.lang.Thread 实例无法访问?”

最佳答案

我也遇到了我们网站的内存泄漏问题,
使用 yourkit java profiler 提供大量信息,并且凭借它的能力,您可以在所有内存都被利用的情况下获得更广泛的图像。
您可以使用上述工具找到很棒的教程 Find Java Memory Leaks

你的问题,

"What kind of Objects are there that are not reachable from an instance of java.lang.Thread other then Objects in the Finalizer Queue and unreferenced objects pending GC?"

对象有四种,

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

除了这些 JVM 还使用 native 内存,您可以在 IBM Heap and native memory use by the JVMThanks for the memory 上找到其信息,根据 YourKit,JVM Memory Structure 具有非堆内存,根据它们的定义是

Also, the JVM has memory other than the heap, referred to as non-heap memory. It is created at the JVM startup and stores per-class structures such as runtime constant pool, field and method data, and the code for methods and constructors, as well as interned Strings.

关于java - 当线程无法访问所有使用的堆时发现 Java 内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20637446/

相关文章:

java - Java中是否存在内存泄漏

c++ - 使用单例时内存泄漏

java - 遇到 Java 数组索引错误

java - Spring MVC 和 JSP : How to pass a parameter from the controller to JSP?

java - 在 PHP 上使用 RegEx 时遇到的问题

java - 为什么允许向上转换数组,而不允许使用泛型?

visual-studio - 随机命名的模块

WCF 无法再介入本地托管的服务 - 为什么不呢?

perl - 如何调查 "Attempt to free unreferenced scalar"

c# - 我是否需要取消订阅 Click 事件以防止内存泄漏?