为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

芜湖不芜 2022-09-28 16:25:50
我有一个似乎正在泄漏内存的java应用程序,但我无法找到确定根本原因的方法。我从内存MXBean中获得的堆内存使用量似乎与我从堆转储中获得的堆内存使用量相差很大。根据:((double) memoryMXBean.getHeapMemoryUsage().getUsed()) / (1024 * 1024)随着时间的推移,堆内存使用量从开始时的 55MB 增加到运行 4 天后的 90MB。但是,开始时收集的堆转储在运行4天时为28.7MB和34MB。              MemoryMXBean  heap_dumpbeginning             55MB     28.7MBafter 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>我的问题是:为什么 mxbean 中的堆使用数与堆转储中的堆使用数不一致?甚至 mxbean 所说的 (90 - 55 = 35MB) 之间的差异与堆转储中的数字之间的差异(34 - 28.7 = 5.3MB)不一致,为什么?应用程序启动后的堆转储在堆转储中具有以下信息:Used heap dump  28.7 MBNumber of objects   594,867Number of classes   8,929Number of class loaders 84Number of GC roots  2,710Format  hprofJVM version Time    2:30:45 PM PDTDate    Apr 8, 2019Identifier size 64-bitCompressed object pointers  trueFile path   /tmp/20190408_lessThanOneDay_6168.hprofFile length 71,387,808已运行 4 天的堆转储为:Used heap dump  34 MBNumber of objects   677,239Number of classes   9,162Number of class loaders 92Number of GC roots  2,859Format  hprofJVM version Time    9:00:15 AM PDTDate    Apr 8, 2019Identifier size 64-bitCompressed object pointers  trueFile path   /tmp/20190408_4days_19324.hprofFile length 120,467,694
查看完整描述

1 回答

?
RISEBY

TA贡献1856条经验 获得超5个赞

堆转储格式不包含完整信息,例如关于内存填充的信息,并强制显示工具进行猜测。请参阅堆转储对您撒谎的文章 关于 深入探讨问题详细信息,显示工具将显示不同的估计值。它总结为:

  • 大多数基于 HPROF 的工具在推导实际实例占用空间时都存在问题。本文中的特殊示例显示,实际实例大小和估计实例大小之间存在> 25% 的差异,这可能导致分析朝着错误的方向发展。但是,这种情况很少见,大多数分析应该没问题,尤其是在处理价值千兆字节的内存泄漏时。

  • 有一些谈判要修复HPROF,但他们最终以底线“我们只是需要一个更好的格式”结束,因为工具已经对HPROF的实际含义有所保留。杰普,有人吗?

  • 在线工具是找出实际实例占用空间的最佳方法。使用JOL,通过命令行运行它,将其嵌入到您的项目中。你永远不要通过查看堆转储来猜测对象布局。


查看完整回答
反对 回复 2022-09-28
  • 1 回答
  • 0 关注
  • 59 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信