繁体   English   中英

为什么MxBean的堆用法与堆转储中的用法不同?

[英]Why is heap usage from MxBean different from that in heap dump?

我有一个Java应用程序,似乎正在泄漏内存,但是我无法找到确定根本原因的方法。 而且我从MemoryMXBean获得的堆内存使用量与我从堆转储中获得的内存似乎相当不一样。

根据:

((double) memoryMXBean.getHeapMemoryUsage().getUsed()) / (1024 * 1024)

随时间推移,堆内存使用量从开始的55MB增加到运行4天后的90MB。

但是开始运行4天后收集的堆转储为28.7MB和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>

我的问题是:

  1. 为什么mxbean的堆使用数量与堆转储中的使用数量不一致?
  2. 甚至mxbean所说的差异(90-55 = 35MB)与堆转储数之间的差异(34-28.7 = 5.3MB)都不一致,为什么?

启动后,应用程序的堆转储在堆转储中具有以下信息:

Used heap dump  28.7 MB
Number of objects   594,867
Number of classes   8,929
Number of class loaders 84
Number of GC roots  2,710
Format  hprof
JVM version 
Time    2:30:45 PM PDT
Date    Apr 8, 2019
Identifier size 64-bit
Compressed object pointers  true
File path   /tmp/20190408_lessThanOneDay_6168.hprof
File length 71,387,808

已运行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的实际含义有所保留。 JEP,有人吗?
  • 在线工具是找出实际实例占用空间的最佳方法。 使用JOL,通过命令行运行它,并将其嵌入到您的项目中。 永远不要,不要通过查看堆转储来猜测对象的布局。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM