已用、已提交和最大堆内存的差异
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 虚拟机可能无法分配内存,即使 已用内存不超过此最大大小。
【讨论】:
已提交内存和最大内存之间有什么区别(或者更确切地说,两者兼有有什么意义)? @dtccommitted
将以-Xms
开头(并且可能会增长),而max
将是上限:例如-Xmx
。我猜used
在这种情况下意味着:驻留 + 交换页面。
那么used 和commited 的区别是commited 是保证JVM 可以使用的吗?这是否意味着使用过的JVM不能保证使用?对不起,但这个答案并没有解释有什么区别。
@tolache 似乎已承诺已保证(将来可能会使用),used 当前正在使用中(因此不需要未来保证,它已被消耗)。对于 max,其允许的扩展提供的内存在需要时可用。【参考方案2】:
已用内存是当前使用的内存量,以字节为单位,而提交的内存以字节为单位显示提交给 JVM 使用的内存量。
【讨论】:
【参考方案3】:第一个used < committed < max
,所有的度量单位都是字节
-Xms
cli 选项控制。见2
used:实际使用的内存量,即所有对象所消耗的内存,包括无法访问但尚未被垃圾回收的对象。
可以低于init
committed:当前在操作系统级别为 JVM 进程保留的内存量。
它可以等于或大于 used,JVM 可以从操作系统请求/分配更多内存而不真正使用它,但操作系统无论如何都会为 java 进程保留该内存。
它可能会下降,它甚至可能低于 init,因为 JVM 可以将内存释放回操作系统。
如果 JVM 需要更多内存,则会尝试从操作系统分配更多内存,然后 committed 会上升,但即使请求的内存量为低于 最大
如果您尝试创建新对象并且 used < committed
则 JVM 不需要需要从操作系统请求更多内存,因此 保证它将成功。
如果您尝试创建新对象并且内存总量将超过committed
,则 JVM 需要在创建对象之前从操作系统分配更多内存,这不能保证成功(操作系统也可能内存不足)
max:JVM 将尝试从操作系统请求/分配的最大内存量
由-Xmx
cli 选项控制。见2
不保证 JVM 能够分配这么多,操作系统可能会因为其他进程保留它而耗尽内存。
所以在 OP 示例中
二手是3.8G committed 和 max 为 8.6G这意味着 JVM 可以在堆中分配高达 8.6G 的对象,这是保证,它不必询问操作系统,因为它已经分配了。如果 JVM 在某个时候需要更多的内存,因为它需要分配更多的对象并且它不能通过垃圾收集释放任何内存,那么它将因 OOM 失败,因为 8.6G 已经是 max允许请求(我猜是因为它以-Xmx8600M
开头。
【讨论】:
以上是关于已用、已提交和最大堆内存的差异的主要内容,如果未能解决你的问题,请参考以下文章