使用,提交和最大堆内存的差异

Alo*_*lok 32 java jvm memory-management apache-spark spark-streaming

我正在监视OutOfMemoryException的spark执行器JVM.我使用Jconsole连接到执行程序JVM.以下是Jconsole的快照: 在此输入图像描述

在图像中使用的内存显示为3.8G,提交的内存为8.6G,最大内存也是8.6G.任何人都可以解释使用和提交的内存或任何解释它的链接之间的区别.

ece*_*ulm 35

首先used < committed < max,所有这些的计量单位都是字节

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

所以在OP的例子中

  • 使用的是3.8G
  • 承诺最大为 8.6G

这意味着 JVM 可以在堆中分配最多 8.6G 的对象,这是有保证的,它不必向操作系统询问,因为它已经分配了。如果 JVM 在某个时候需要比这更多的内存,因为它需要分配更多的对象并且无法通过垃圾回收释放任何内存,那么它将因 OOM 而失败,因为 8.6G 已经是它允许请求的最大值(我因为它是从 开始的-Xmx8600M


mus*_*ibs 23

来自Java Doc MemoryUsage,

getUsed是:

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

getCommitted()

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

GetMax的()

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

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

  • @dtc `commited` 将以 `-Xms` 开头(并且可能增长),而 `max` 将是上限:例如 `-Xmx`。我想在这种情况下“已使用”意味着:驻留+交换页面。 (2认同)