猿问

javacore 和 heapdump 中的堆大小:IBM JVM 上的 20 倍差异

注意到生产服务器 (Websphere8.5.5) 开始消耗大量内存。


javacore dump 中的数字清楚地表明罪魁祸首是一个过度生长的堆:


|  +--Memory Manager (GC): 5,496,900,272 bytes / 3193 allocations

|  |  |

|  |  +--Java Heap: 5,368,770,560 bytes / 1 allocation

|  |  |

|  |  +--Other: 128,129,712 bytes / 3192 allocations  

但同时,在 MAT 中打开的 heap dump 报告堆的总体积约为 200M(有时高达 300M,但绝不会更多)。


它的真正含义是什么?堆转储值得信赖吗?如果是,有没有办法释放未使用的堆内存?


慕哥9229398
浏览 248回答 1
1回答

蓝山帝景

该NATIVEMEMINFO部分显示了虚拟内存,因此5,368,770,560仅表示 JVM 已为堆虚拟分配了那么多内存。实际驻留多少将取决于实际堆大小和堆使用情况。例如,如果在tenured region中堆积了大量垃圾,然后在full GC中被清除,那么这些页面可能在某个时候成为常驻页面,但实际存活的数量取决于许多因素。我相信当 JVM 启动时,它实际上分配了 的完整大小,-Xmx所以我认为你总是会在 NATIVEMEMINFO 中看到堆的完整大小(也可能是它只分配了-Xms,所以如果你看到的大于-Xms,那么这意味着压力驱动堆增加[当然,注意正常的锯齿])。当您在 MAT 中加载转储时,它会运行完整的垃圾回收并默认从主视图中删除所有无法访问的对象。您可以单击“概览”页面上的“无法访问的对象直方图”链接并滚动到底部的浅堆总数总和行,以查看堆转储中有多少“垃圾”。MAT 首选项中还有一个选项“保留无法访问的对象”,它将所有这些对象保留在主 MAT 视图中,但这通常不是很有用。所以基本的答案是 MAT 只显示活动对象,所以在你转储时,有 200-300MB 的活动对象。其余的可能在垃圾箱中,或者根本不存在,而 NATIVEMEMINFO 只是显示虚拟大小。随着时间的推移查看堆使用情况的更好方法是在GCMV 中使用 verbosegc 和 load :-Xverbosegclog:verbosegc.%seq.log,20,50000
随时随地看视频慕课网APP

相关分类

Java
我要回答