Java 为什么MxBean中的堆使用与堆转储中的不同?
我有一个java应用程序,它似乎正在泄漏内存,但我还没有找到一种方法来确定根本原因。我从MemoryMXBean获得的堆内存使用量似乎与我从堆转储获得的堆内存使用量相差甚远 根据:Java 为什么MxBean中的堆使用与堆转储中的不同?,java,memory-leaks,Java,Memory Leaks,我有一个java应用程序,它似乎正在泄漏内存,但我还没有找到一种方法来确定根本原因。我从MemoryMXBean获得的堆内存使用量似乎与我从堆转储获得的堆内存使用量相差甚远 根据: ((double) memoryMXBean.getHeapMemoryUsage().getUsed()) / (1024 * 1024) 堆内存使用量随着时间的推移从开始时的55MB增加到运行4天后的90MB MemoryMXBean heap_dump beginning
((double) memoryMXBean.getHeapMemoryUsage().getUsed()) / (1024 * 1024)
堆内存使用量随着时间的推移从开始时的55MB增加到运行4天后的90MB
MemoryMXBean heap_dump
beginning 55MB 28.7MB
after 4 days 90MB 34MB
但是,在开始时收集的堆转储为28.7MB,在运行4天时为34MB
MemoryMXBean heap_dump
beginning 55MB 28.7MB
after 4 days 90MB 34MB
该应用程序是基于工作的。这意味着它大部分时间都处于空闲状态,直到生成工作负载的日常作业启动。可以看出,堆内存使用量从55MB左右开始,每天增加一次,直到应用程序重新启动。在没有部署的几天后达到峰值时,堆的使用量可能高达110MB
以下是应用程序的启动方式:
jdk1.8/bin/java
-Dpid=29816
-Dscript=someApp
-Djdbc.drivers=someDriver
-Xmx256M
-Duser.timezone=UTC
-Djavax.net.ssl.trustStore=someTrustStore.jks
-Djavax.net.ssl.trustStorePassword=*****
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-XX:+PrintTenuringDistribution
-XX:+PrintGCCause
-XX:+PrintGCApplicationStoppedTime
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/tmp/output/logs
-Xloggc:/tmp/output/logs/someApp-gclog
package.SomeApp
我通过以下命令从服务器获得堆转储:
jmap -dump:format=b,file=<FILENAME> <PID>
已运行4天的堆转储为:
Used heap dump 34 MB
Number of objects 677,239
Number of classes 9,162
Number of class loaders 92
Number of GC roots 2,859
Format hprof
JVM version
Time 9:00:15 AM PDT
Date Apr 8, 2019
Identifier size 64-bit
Compressed object pointers true
File path /tmp/20190408_4days_19324.hprof
File length 120,467,694
堆转储格式不包含完整信息,例如关于内存填充的信息,并强制显示工具猜测。请参阅深入问题细节的文章,该文章显示工具将显示不同的估计。总结起来是:
- 大多数基于HPROF的工具在推导实际实例足迹方面存在问题;本文中特制的示例显示实际实例大小与估计实例大小之间的差异大于25%,这可能导致分析方向错误。然而,这样的情况很少见,大多数分析都应该很好,特别是在处理千兆字节的内存泄漏时
- 曾经有过关于修复HPROF的谈判,但他们最终以“我们只需要一个更好的格式”作为底线,因为工具已经对HPROF的实际含义有所保留。杰普,有人吗
- 在线工具是计算实际实例占用空间的最佳工具。使用JOL,通过命令行运行它,将其嵌入到项目中。不要通过查看堆转储来猜测对象布局