当并非所有已用堆都可以从线程访问时查找 Java 内存泄漏
我正在研究基于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,我应该在哪里查找填充堆所需的其他 2.5 GB?- 终结器队列中没有任何内容 - 没有大量无法访问的对象等待 GC
我认为提出这个问题的另一种方法是:“如何找到所有无法从java.lang.Thread实例访问的对象?也许是一个 OQL 查询?,另一个问题是:“有哪些类型的对象无法从 java.lang.Thread 的实例访问,然后是终结器队列中的对象和未引用的对象挂起的 GC?