Why does the JVM Heap Usage Max as reported by JMX change over time?

浪子不回头ぞ 提交于 2020-01-03 08:08:14

问题


My JVM heap max is configured at 8GB on the name node for one of my hadoop clusters. When I monitor that JVM using JMX, the reported maximum is constantly fluctuating, as shown in the attached image.

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

I only see this behavior on one (the most active) of my hadoop clusters. On the other clusters the reported maximum stays fixed at the configured value. Any ideas why the reported maximum would change?

Update:

The java version is "1.6.0_20"

The heap max value is set in hadoop-env.sh with the following line:

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

ps shows:

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

Update 2:

Added the -Xms8G switch to the startup command line last night:

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

As shown in the image below, the max value still varies, although the pattern seems to have changed.

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

Update 3:

Here's a new graph that also shows Non-Heap max, which stays constant:

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


回答1:


According to the MemoryMXBean documentation, memory usage is reported in two categories, "Heap" and "Non-Heap" memory. The description of the Non-Heap category says:

The Java virtual machine manages memory other than the heap (referred as non-heap memory). The Java virtual machine has a method area that is shared among all threads. The method area belongs to non-heap memory. It stores per-class structures such as a runtime constant pool, field and method data, and the code for methods and constructors. It is created at the Java virtual machine start-up.

The method area is logically part of the heap but a Java virtual machine implementation may choose not to either garbage collect or compact it. Similar to the heap, the method area may be of a fixed size or may be expanded and shrunk. The memory for the method area does not need to be contiguous.

This description sounds a lot like the permanent generation (PermGen), which is indeed part of the heap and counts against the memory allocated using the -Xmx flag. I'm not sure why they decided to report this separately since it is part of the heap.

I suspect that the fluctuations you're seeing are a result of the JVM shrinking and growing the permanent generation, which would cause the reported max heap space available for non-PermGen uses to change accordingly. If you could get a sum of the Heap and Non-Heap maxes as reported by JMX and this sum stays constant at the 8G limit, that would verify this hypothesis.




回答2:


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)



来源:https://stackoverflow.com/questions/11905220/why-does-the-jvm-heap-usage-max-as-reported-by-jmx-change-over-time

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!