为什么我的垃圾收集日志显示3.8GB作为最大可用堆大小,而我已经分配了4GB作为最大堆大小?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么我的垃圾收集日志显示3.8GB作为最大可用堆大小,而我已经分配了4GB作为最大堆大小?相关的知识,希望对你有一定的参考价值。

我在64位RHEL 6计算机上安装了64位热点JDK 1.7.0版。我为tomcat应用程序使用以下JVM选项。

CATALINA_OPTS="${CATALINA_OPTS} -Dfile.encoding=UTF8 -Dorg.apache.catalina.loader.WebappClassLoader.ENABLE_CLEAR_REFERENCES=false -Duser.timezone=EST5EDT"

# General Heap sizing
CATALINA_OPTS="${CATALINA_OPTS} -Xms4096m -Xmx4096m -XX:NewSize=2048m -XX:MaxNewSize=2048m -XX:PermSize=512m -XX:MaxPermSize=512m -XX:+UseCompressedOops -XX:+DisableExplicitGC"

# Enable the CMS GC policy
CATALINA_OPTS="${CATALINA_OPTS} -XX:+UseConcMarkSweepGC -XX:CMSWaitDuration=15000 -XX:+CMSParallelRemarkEnabled -XX:+CMSCompactWhenClearAllSoftRefs -XX:+CMSConcurrentMTEnabled -XX:+CMSScavengeBeforeRemark -XX:+CMSClassUnloadingEnabled"

# Verbose Garbage Collection Logging
CURRENT_DATE=`date +%Y%m%d%H%M%S`
CATALINA_OPTS="${CATALINA_OPTS} -verbose:gc -XX:+PrintGCDetails -Xloggc:${CATALINA_BASE}/logs/gc-${CURRENT_DATE}.log -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution"

当我进行垃圾收集分析时,GC日志显示最大可用堆只有3.8GB而不是4GB分配给JVM。这是为什么?

答案

新一代(2048M)由80%伊甸园(1638.4M)和两个幸存者空间(每个10%或204.8M)组成:

Heap
 par new generation   total 1887488K, used 134226K [0x00000006fae00000, 0x000000077ae00000, 0x000000077ae00000)
  eden space 1677824K,   8% used [0x00000006fae00000, 0x00000007031148e0, 0x0000000761480000)
  from space 209664K,   0% used [0x0000000761480000, 0x0000000761480000, 0x000000076e140000)
  to   space 209664K,   0% used [0x000000076e140000, 0x000000076e140000, 0x000000077ae00000)
 concurrent mark-sweep generation total 2097152K, used 242K [0x000000077ae00000, 0x00000007fae00000, 0x00000007fae00000)

任何时候幸存者空间之一都是空的(见Generations)。 因此,有用的堆大小是1638.4 + 204.8 + 2048 = 3891.2 MB

以上是关于为什么我的垃圾收集日志显示3.8GB作为最大可用堆大小,而我已经分配了4GB作为最大堆大小?的主要内容,如果未能解决你的问题,请参考以下文章

Java G1垃圾收集器占用大量内存

为什么Spark运行的内存少于可用内存?

即使在需要时也不会进行垃圾收集

GC垃圾回收 | 深入理解G1垃圾收集器和GC日志

《深入理解java虚拟机》笔记JVM调优(分代垃圾收集器)

JVM垃圾回收篇(扩展知识)