java内存泄漏,visualvm显示错误的数据

时间:2014-01-27 09:01:15

标签: java memory-leaks profiling visualvm

我运行了一个java应用程序,几小时后它就会运行内存。 我试图用visualvm检测内存泄漏,但它显示错误的数据(不知道如何发生)。

在屏幕截图中,您可以看到任务管理器显示700Mb的内存使用情况,visualvm显示225 ...

有谁知道这里发生了什么?

此致

enter image description here

3 个答案:

答案 0 :(得分:4)

请注意,您的操作系统只知道java在一段时间内保留的内存总量(并且java不会轻易返回该内存量AFAIK)。但是java可能没有在给定时刻使用所有内存,因此您可以看到这两个数字之间的差异。

例如,如果你像这样启动程序

java -Xmx512m -Xms256m ...

然后你的JVM一启动就会占用256 MB(操作系统会或多或少地告诉你)。但是,如果你打开你的内存窥视工具(无论是visualvm,jconsole等),它可能表明你使用的不到那个(只是你不需要使用整个保留堆)。

答案 1 :(得分:3)

Java不会返回它。分配内存需要花费很多精力,因此Java通常不会返回系统曾授予它的任何内存。因此,如果您的程序使用过760 MB RAM,那么这就是它所坚持的。

然后还有另外两个因素起着重要作用。堆大小只是程序使用或可以使用的内存量。但是在你的程序和操作系统之间是Java-VM,它也可能占用大量内存。任务管理器会显示程序使用的内存量以及虚拟机。

另一个因素是内存碎片。一些数据结构(例如阵列)必须位于存储器的连续块中。 array [i + 1]必须位于array [i]之后的内存槽中。现在这意味着如果你有例如分配了10 MB内存,使用了中间2 MB内存,并且您希望创建一个6 MB阵列,Java-VM必须分配新内存,因此它可以将阵列整合在一起。 这会增加任务管理器中的内存使用量,但不会增加堆大小,因为堆大小只显示实际使用的内存。

答案 2 :(得分:2)

Java中的内存空间由3个度量标准定义:used,available,max available(请参阅JMX值)。您看到的大小是可用大小而不是最大可用大小,可能已经分配。 同样,您还应该显示非堆内存(通常小于堆,但您应该以不同的方式设置它) 更准确地说,您应该发布JVM启动设置。

PS:查看你的内存配置文件我看不到任何泄漏:我可以看到JVM缩小了堆大小,因为它根本没有使用