10

我的 JVM 堆最大值在我的一个 hadoop 集群的名称节点上配置为 8GB。当我使用 JMX 监控 JVM 时,报告的最大值不断波动,如附图所示。

http://highlycaffeinated.com/assets/images/heapmax.png

我只在我的一个(最活跃的)hadoop 集群上看到这种行为。在其他集群上,报告的最大值固定在配置的值。任何想法为什么报告的最大值会改变?

更新:

java版本是“1.6.0_20”

堆最大值在 hadoop-env.sh 中使用以下行设置:

export HADOOP_NAMENODE_OPTS="-Xmx8G -Dcom.sun.management.jmxremote.port=8004 $JMX_SHARED_PROPS"

ps显示:

hadoop 27605 1 99 Jul30 ? 11-07:23:13 /usr/lib/jvm/jre/bin/java -Xmx1000m -Xmx8G

更新 2:

-Xms8G昨晚在启动命令行中添加了开关:

export HADOOP_NAMENODE_OPTS="-Xms8G -Xmx8G -Dcom.sun.management.jmxremote.port=8004 $JMX_SHARED_PROPS"

如下图所示,尽管模式似乎发生了变化,但最大值仍然不同。

http://highlycaffeinated.com/assets/images/heapmax2.png

更新 3:

这是一个新图表,它还显示了非堆最大值,它保持不变:

http://highlycaffeinated.com/assets/images/heapmax3.png

4

2 回答 2

1

根据MemoryMXBean文档,内存使用情况分为两类,“堆”和“非堆”内存。非堆类别的描述说:

Java 虚拟机管理堆以外的内存(称为非堆内存)。Java 虚拟机有一个在所有线程之间共享的方法区。方法区属于非堆内存。它存储每个类的结构,例如运行时常量池、字段和方法数据,以及方法和构造函数的代码。它是在 Java 虚拟机启动时创建的。

方法区在逻辑上是堆的一部分,但 Java 虚拟机实现可以选择不进行垃圾收集或压缩它。与堆类似,方法区可以是固定大小的,也可以是扩展和收缩的。方法区的内存不需要是连续的。

这个描述听起来很像永久代(PermGen),它确实是堆的一部分,并计入使用-Xmx标志分配的内存。我不确定他们为什么决定单独报告这个,因为它是堆的一部分。

我怀疑您看到的波动是 JVM 缩小和增长永久代的结果,这将导致报告的可用于非 PermGen 的最大堆空间相应地发生变化。如果您可以获得 JMX 报告的堆和非堆最大值的总和,并且该总和在 8G 限制下保持不变,那将验证这个假设。

于 2012-08-15T14:36:07.690 回答
0

One possibility is that the JVM survivor space is fluctuating in max-size.

The JVM max-size reported by JMX via the HeapMemoryUsage.max attribute is not the actual max-size of the heap (i.e. the one set with -Xmx )

The reported value is the max heap size minus the max survivor space size

To get the total max heap size, add the two jmx attributes:

java.lang:type=Memory/HeapMemoryUsage.max + java.lang:type=MemoryPool,name=Survivor Space/Usage.max

(tested on oracle jdk 1.7.0_45)

于 2014-02-21T09:59:24.190 回答