我运行了一个java应用程序,几小时后它就会运行内存。 我试图用visualvm检测内存泄漏,但它显示错误的数据(不知道如何发生)。
在屏幕截图中,您可以看到任务管理器显示700Mb的内存使用情况,visualvm显示225 ...
有谁知道这里发生了什么?
此致
答案 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缩小了堆大小,因为它根本没有使用