我的JVM堆max在名称节点上配置为8GB,用于我的一个hadoop集群。当我使用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:
这是一个新的图表,也显示了非堆最大值,它保持不变:
答案 0 :(得分:1)
根据MemoryMXBean文档,内存使用情况分为两类:“Heap”和“Non-Heap”内存。非堆类别的描述说:
Java虚拟机管理堆以外的内存(称为非堆内存)。 Java虚拟机具有在所有线程之间共享的方法区域。方法区域属于非堆内存。它存储每类结构,例如运行时常量池,字段和方法数据,以及方法和构造函数的代码。它是在Java虚拟机启动时创建的。
方法区域在逻辑上是堆的一部分,但Java虚拟机实现可能选择不垃圾收集或压缩它。与堆类似,方法区域可以是固定大小的,也可以是扩展和收缩的。方法区域的内存不需要是连续的。
这个描述听起来很像永久代(PermGen),它确实是堆的一部分,并且使用-Xmx
标志分配内存。我不确定为什么他们决定单独报告这个,因为它是堆的一部分。
我怀疑您看到的波动是JVM缩小并增加永久生成的结果,这将导致报告的非PermGen使用的最大堆空间相应地更改。如果你能得到JMX报告的Heap和Non-Heap maxes的总和,并且这个总和保持在8G的限制,那将验证这个假设。
答案 1 :(得分:0)
一种可能性是JVM幸存者空间在max-size中波动。
JMX通过HeapMemoryUsage.max属性报告的JVM max-size不是堆的实际最大大小(即使用-Xmx设置的那个)
报告的值是最大堆大小减去最大幸存者空间大小
要获取总的最大堆大小,请添加两个jmx属性:
java.lang:type=Memory/HeapMemoryUsage.max + java.lang:type=MemoryPool,name=Survivor Space/Usage.max
(在oracle jdk 1.7.0_45上测试)