为什么 MxBean 中的堆使用情况与堆转储中的堆使用情况不同?

为什么 MxBean 中的堆使用情况与堆转储中的堆使用情况不同?

我有一个 Java 应用程序似乎正在泄漏内存,但我无法找到确定根本原因的方法。而且我拥有的堆内存使用量来自 MemoryMXBean似乎与我得到的完全不同来自堆转储

根据:

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

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

但是一开始收集的堆转储是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>

我的问题是:

  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

相关内容