为什么我的Java堆转储大小比使用的内存小得多?

问题

我们正试图在我们的Web应用程序中找到导致大量内存泄漏的元凶。我们在发现内存泄漏方面经验有限,但是我们发现了如何使用jmapEclipse

MAT进行Java堆转储并对其进行分析。

但是,对于我们使用56 / 60GB内存的应用程序,堆转储的大小仅为16GB,而在Eclipse MAT中则更少。

回答:

我们的服务器将Ubuntu 14.04上的Wildfly

8.2.0用于我们的Java应用程序,其进程使用了​​95%的可用内存。进行转储时,我们的缓冲区/缓存使用空间为56GB。

我们使用以下命令创建转储: sudo -u {application user} jmap

-dump:file=/mnt/heapdump/dump_prd.bin {pid}

堆转储文件的大小为16,4GB,当使用Eclipse MAT分析时,它表示大约有1GB的活动对象和约14.8GB的不可用/浅堆。

这是有关我们看到的问题的更多信息。我们会监控内存使用情况,并且看到它不断增长,直到剩下约300mb的可用内存为止。然后,它将停留在该内存量附近,直到进程崩溃为止,不幸的是,应用程序日志中没有错误。

这使我们假设这是一个硬OOM错误,因为仅当内存快要用尽时才会发生。我们使用-Xms25000m -Xmx40000mJVM 的设置。

回答:

基本上,我们想知道为什么我们的大部分内存没有在此转储中捕获。保留的顶级大小类看起来不太可疑,因此我们想知道是否存在与堆转储有关的错误。

回答:

转储堆时,JVM将首先运行垃圾回收周期以释放所有无法访问的对象。

如何在不首先进行垃圾收集的情况下在Java

5上进行堆转储?

以我的经验,在真正的OutOfMemoryError中,您的应用程序仅需要比可用空间更多的堆空间,此GC是一个愚蠢的事情,最终的堆转储将为最大大小。堆大小。

当堆转储小得多时,这意味着系统并不是真正的内存不足,而是可能有内存压力。例如,存在java.lang.OutOfMemoryError: GC

overhead limit exceeded错误,这意味着JVM可能已经能够释放足够的内存来满足某些新的分配请求,但是它不得不花费太多时间来收集垃圾。

您也可能没有内存问题。是什么让您觉得自己呢?您没有提及有关堆使用或OutOfMemoryError的任何信息。您仅提到了JVM在操作系统上的内存占用量。

以上是 为什么我的Java堆转储大小比使用的内存小得多? 的全部内容, 来源链接: utcz.com/qa/398406.html

回到顶部