已用、已提交和最大堆内存的差异

Posted

技术标签:

【中文标题】已用、已提交和最大堆内存的差异【英文标题】:Difference in Used, Committed and Max Heap Memory 【发布时间】:2017-05-19 00:43:45 【问题描述】:

我正在监视 OutOfMemoryException 的 spark executor JVM。我使用 Jconsole 连接到执行程序 JVM。以下是 Jconsole 的快照:

图中已用内存显示为 3.8G,已提交内存为 8.6G,Max memory 也为 8.6G 谁能解释已用内存和已提交内存之间的区别或任何解释它的链接。

【问题讨论】:

docs.oracle.com/javase/7/docs/api/java/lang/management/… Why does a JVM report more committed memory than the linux process resident set size?的可能重复 【参考方案1】:

来自MemoryUsage的Java Doc,

getUsed 是:

以字节为单位的已用内存量

getCommitted()

返回为 Java 提交的内存量(以字节为单位) 要使用的虚拟机。这个内存量是保证的 要使用的 Java 虚拟机。

getMax()

返回可用于的最大内存量(以字节为单位) 内存管理。如果最大内存大小,此方法返回 -1 未定义。

此内存量不保证可用于内存 如果它大于提交的内存量,则进行管理。这 Java 虚拟机可能无法分配内存,即使 已用内存不超过此最大大小。

【讨论】:

已提交内存和最大内存之间有什么区别(或者更确切地说,两者兼有有什么意义)? @dtc committed 将以-Xms 开头(并且可能会增长),而max 将是上限:例如-Xmx。我猜used 在这种情况下意味着:驻留 + 交换页面。 那么used 和commited 的区别是commited 是保证JVM 可以使用的吗?这是否意味着使用过的JVM不能保证使用?对不起,但这个答案并没有解释有什么区别。 @tolache 似乎已承诺已保证(将来可能会使用),used 当前正在使用中(因此不需要未来保证,它已被消耗)。对于 max,其允许的扩展提供的内存在需要时可用。【参考方案2】:

已用内存是当前使用的内存量,以字节为单位,而提交的内存以字节为单位显示提交给 JVM 使用的内存量。

【讨论】:

【参考方案3】:

第一个used < committed < max,所有的度量单位都是字节

init:JVM 在启动时向操作系统请求的初始内存量。 这由 java 命令的-Xms cli 选项控制。见2 used:实际使用的内存量,即所有对象所消耗的内存,包括无法访问但尚未被垃圾回收的对象。 可以低于init committed:当前在操作系统级别为 JVM 进程保留的内存量。 它可以等于或大于 used,JVM 可以从操作系统请求/分配更多内存而不真正使用它,但操作系统无论如何都会为 java 进程保留该内存。 它可能会下降,它甚至可能低于 init,因为 JVM 可以将内存释放回操作系统。 如果 JVM 需要更多内存,则会尝试从操作系统分配更多内存,然后 committed 会上升,但即使请求的内存量为低于 最大 如果您尝试创建新对象并且 used < committed 则 JVM 不需要需要从操作系统请求更多内存,因此 保证它将成功。 如果您尝试创建新对象并且内存总量将超过committed,则 JVM 需要在创建对象之前从操作系统分配更多内存,这不能保证成功(操作系统也可能内存不足) ma​​x:JVM 将尝试从操作系统请求/分配的最大内存量 由-Xmx cli 选项控制。见2 不保证 JVM 能够分配这么多,操作系统可能会因为其他进程保留它而耗尽内存。

所以在 OP 示例中

二手是3.8G committedma​​x 为 8.6G

这意味着 JVM 可以在堆中分配高达 8.6G 的对象,这是保证,它不必询问操作系统,因为它已经分配了。如果 JVM 在某个时候需要更多的内存,因为它需要分配更多的对象并且它不能通过垃圾收集释放任何内存,那么它将因 OOM 失败,因为 8.6G 已经是 ma​​x允许请求(我猜是因为它以-Xmx8600M 开头。

【讨论】:

以上是关于已用、已提交和最大堆内存的差异的主要内容,如果未能解决你的问题,请参考以下文章

JVM启动参数

手动实现最小堆和最大堆(优先队列)

JVM优化

JVM调优常用参数配置

jvm参数

python 实现堆和堆排序