为什么我的Java堆转储大小比使用的内存小得多? [英] Why is my Java heap dump size much smaller than used memory?

查看:464
本文介绍了为什么我的Java堆转储大小比使用的内存小得多?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正试图在我们的Web应用程序中找到大内存泄漏的罪魁祸首。我们在查找内存泄漏方面经验非常有限,但我们发现如何使用 jmap 进行java堆转储并在Eclipse MAT中进行分析。

We are trying to find the culprit of a big memory leak in our web application. We have pretty limited experience with finding a memory leak, but we found out how to make a java heap dump using jmap and analyze it in Eclipse MAT.

但是,我们的应用程序使用56 / 60GB内存,堆转储的大小只有16GB,在Eclipse MAT中甚至更少。

However, with our application using 56/60GB memory, the heap dump is only 16GB in size and is even less in Eclipse MAT.

我们的服务器在Ubuntu 14.04上使用Wildfly 8.2.0作为我们的java应用程序,其过程使用95可用内存的百分比。进行转储时,我们的缓冲区/缓存已用空间为56GB。

Our server uses Wildfly 8.2.0 on Ubuntu 14.04 for our java application, whose process uses 95% of the available memory. When making the dump, our buffers/cache used space was at 56GB.

我们使用以下命令创建转储: sudo -u {应用程序用户} jmap -dump:file = / mnt / heapdump / dump_prd.bin {pid}

We used the following command to create the dump: sudo -u {application user} jmap -dump:file=/mnt/heapdump/dump_prd.bin {pid}

堆转储文件大小为16, 4GB并且在使用Eclipse MAT进行分析时,它表示有大约1GB的活动对象和大约14,8GB的无法访问/浅堆。

The heap dump file size is 16,4GB and when analyzing it with Eclipse MAT, it says there are around 1GB live objects and ~14,8GB unreachable/shallow heap.

编辑:以下是我们发现的问题的更多信息。我们监视内存使用情况,我们看到它的增长和增长,直到剩下大约300mb的可用内存。然后它保持在那个内存量附近,直到进程崩溃,遗憾的是应用程序日志中没有错误。

Here is some more info about the problem we see happening. We monitor our memory usage, and we see it grow and grow, until there is ~300mb free memory left. Then it stays around that amount of memory, until the process crashes, unfortunately without error in the application log.

这使我们假设它是一个硬OOM错误,因为这只发生在内存接近耗尽时。我们为JVM使用 -Xms25000m -Xmx40000m 设置。

This makes us assume it is a hard OOM error because this only happens when the memory is near-depleted. We use the settings -Xms25000m -Xmx40000m for our JVM.

基本上,我们想知道为什么我们的大部分内存都没有在这个转储中被捕获。顶部保留的大小类看起来并不太可疑,所以我们想知道是否存在与堆转储有关的问题我们做错了什么。

Basically, we are wondering why the majority of our memory isn't captured in this dump. The top retained size classes don't look too suspicious, so we are wondering if there is something heap dump-related what we are doing wrong.

推荐答案

在转储堆时,JVM将首先运行垃圾收集周期以释放任何无法访问的对象。

When dumping its heap, the JVM will first run a garbage collection cycle to free any unreachable objects.

如何在没有垃圾收集的情况下在Java 5上进行堆转储?

根据我的经验,在一个真正的OutOfMemoryError中你的应用程序只需要比可用的更多的堆空间,这个GC是一个傻瓜的差事,最终的堆转储将是最大的。堆大小。

In my experience, in a true OutOfMemoryError where your application is simply demanding more heap space than is available, this GC is a fool's errand and the final heap dump will be the size of the max. heap size.

当堆转储小得多时,这意味着系统并非真正内存不足,但可能存在内存压力。例如, java.lang.OutOfMemoryError:GC开销限制超出错误,这意味着JVM可能已经能够释放足够的内存来为一些新的分配请求提供服务但是它必须花费太多时间来收集垃圾。

When the heap dump is much smaller, that means the system was not truly out of memory, but perhaps had memory pressure. For example, there is the java.lang.OutOfMemoryError: GC overhead limit exceeded error, which means that the JVM may have been able to free enough memory to service some new allocation request, but it had to spend too much time collecting garbage.

你也可能没有内存问题。是什么让你觉得你这样做?您没有提到有关堆使用或OutOfMemoryError的任何内容。您只提到了JVM在操作系统上的内存占用量。

It's also possible that you don't have a memory problem. What makes you think you do? You didn't mention anything about heap usage or an OutOfMemoryError. You've only mentioned the JVM's memory footprint on the operating system.

这篇关于为什么我的Java堆转储大小比使用的内存小得多?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆