在没有 -XX:+CMSClassUnloadingEnabled 的情况下卸载标准输出日志中的 class 条消息
Unloading class messages in stdout logs without -XX:+CMSClassUnloadingEnabled
我们是 运行 jboss-eap-6.0.1 上的应用程序,java 版本如下所示
$ java -version
java version "1.6.0_45"
Java(TM) SE Runtime Environment (build 1.6.0_45-b06)
Java HotSpot(TM) 64-Bit Server VM (build 20.45-b01, mixed mode)
当堆开始变满时,我开始在 stdout 日志中看到大量 "Unloading class..." 消息,如下所示。我们没有设置 -XX:+CMSClassUnloadingEnabled 标志,根据我的发现,我们不应该卸载 类。我确实在 Atlassian 的站点 (https://confluence.atlassian.com/display/JIRAKB/%5BUnloading+class+sun.reflect.GeneratedMethodAccessor%5D+found+in+Tomcat+logs) 上找到了一个帖子,表明如果 "the JVM finds it physically does not have the resources that have been allocated to it, (usually due to either VM ballooning or resource stealing)",JVM 将卸载 类 而没有设置 -XX:+CMSClassUnloadingEnabled 标志。我没有在其他地方看到过这方面的讨论,想了解 JVM 是否有可能尝试收集 类 作为获得内存的最后努力,或者是否可能有其他一些解释,例如我们在命令行隐式设置 -XX:+CMSClassUnloadingEnabled 标志。任何见解表示赞赏。
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor897]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor709]
[Unloading class sun.reflect.GeneratedConstructorAccessor570]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor996]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor816]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor362]
[Unloading class sun.reflect.GeneratedMethodAccessor257]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor46]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor775]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor210]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor332]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor168]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor149]
命令行选项是
java
-D[Standalone]
-server
-XX:+UseCompressedOops
-XX:+DisableExplicitGC
-Dsun.rmi.dgc.client.gcInterval=36000000
-Dsun.rmi.dgc.server.gcInterval=36000000
-Djs.license.directory=/opt/app/AgentDesktop/resources/jasper
-Djava.io.tmpdir=/opt/tmp
-Xloggc:/opt/app/logs/PRD00_C_gc.log
-XX:+PrintGCTimeStamps
-XX:+PrintGCDetails
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/opt/app/logs/heapDump/PRD00_C
-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog
-Dorg.apache.commons.logging.simplelog.log.org.apache.commons.httpclient.wire=ERROR
-XX:+UseConcMarkSweepGC
-XX:+CMSIncrementalMode
-Xmx2560m
-Xms2560m
-XX:NewSize=512M
-XX:MaxPermSize=512m
-XX:PermSize=256M
-XX:+UseCompressedOops
-XX:AutoBoxCacheMax=2048
-Dorg.jboss.boot.log.file=/opt/app/logs/jboss/PRD00_C/boot.log
-Dlogging.configuration=file:/opt/app/jboss-eap-6.0.1/server/PRD00_C/configuration/logging.properties
-jar
/opt/app/jboss/jboss-modules.jar
-mp
/opt/app/jboss/modules
-jaxpmodule
javax.xml.jaxp-provider
org.jboss.as.standalone
-Djboss.home.dir=/opt/app/jboss
-Djboss.server.base.dir=/opt/app/jboss-eap-6.0.1/server/PRD00_C
--server-config=standalone-full-PRD.xml
--properties=file:/opt/app/AgentDesktop/work/jboss/combined.101932939.properties
-Djboss.socket.binding.port-offset=300
-Djboss.server.base.dir=/opt/app/jboss/server/PRD00_C
-Djboss.server.log.dir=/opt/app/logs/jboss/PRD00_C
-Dcom.kana.properties.url=file:/opt/app/AgentDesktop/work/jboss/combined.101932939.properties
-Dcom.gtnet.systemProperties.override.url=file:/opt/app/AgentDesktop/config/PRD//override.properties
-Dcore.home=/opt/app/AgentDesktop
-Denvironment.dir=/opt/app/AgentDesktop/config/PRD
-Denvironment.url=file:/opt/app/AgentDesktop/config/PRD/
-Drelease.id=1
-Dorg.apache.tomcat.util.http.Parameters.MAX_COUNT=1000
-Dorg.jboss.as.logging.per-deployment=false
-b
0.0.0.0
-XX:+CMSClassUnloadingEnabled
控制在Concurrent-Mark-Sweep循环中是否可以卸载类。但是,即使关闭该选项,类 仍然可以在 Full(停止世界)GC 期间卸载。
使用 CMS 收集器可以触发 Full GC,原因是:
- Concurrent mode failure;
- Promotion failure;
- 显式调用
System.gc
(在您的情况下显然已禁用)。
检查 GC 日志是否包含 (concurrent mode failure)
或 (promotion failed)
消息。
我们是 运行 jboss-eap-6.0.1 上的应用程序,java 版本如下所示
$ java -version
java version "1.6.0_45"
Java(TM) SE Runtime Environment (build 1.6.0_45-b06)
Java HotSpot(TM) 64-Bit Server VM (build 20.45-b01, mixed mode)
当堆开始变满时,我开始在 stdout 日志中看到大量 "Unloading class..." 消息,如下所示。我们没有设置 -XX:+CMSClassUnloadingEnabled 标志,根据我的发现,我们不应该卸载 类。我确实在 Atlassian 的站点 (https://confluence.atlassian.com/display/JIRAKB/%5BUnloading+class+sun.reflect.GeneratedMethodAccessor%5D+found+in+Tomcat+logs) 上找到了一个帖子,表明如果 "the JVM finds it physically does not have the resources that have been allocated to it, (usually due to either VM ballooning or resource stealing)",JVM 将卸载 类 而没有设置 -XX:+CMSClassUnloadingEnabled 标志。我没有在其他地方看到过这方面的讨论,想了解 JVM 是否有可能尝试收集 类 作为获得内存的最后努力,或者是否可能有其他一些解释,例如我们在命令行隐式设置 -XX:+CMSClassUnloadingEnabled 标志。任何见解表示赞赏。
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor897]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor709]
[Unloading class sun.reflect.GeneratedConstructorAccessor570]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor996]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor816]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor362]
[Unloading class sun.reflect.GeneratedMethodAccessor257]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor46]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor775]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor210]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor332]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor168]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor149]
命令行选项是
java
-D[Standalone]
-server
-XX:+UseCompressedOops
-XX:+DisableExplicitGC
-Dsun.rmi.dgc.client.gcInterval=36000000
-Dsun.rmi.dgc.server.gcInterval=36000000
-Djs.license.directory=/opt/app/AgentDesktop/resources/jasper
-Djava.io.tmpdir=/opt/tmp
-Xloggc:/opt/app/logs/PRD00_C_gc.log
-XX:+PrintGCTimeStamps
-XX:+PrintGCDetails
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/opt/app/logs/heapDump/PRD00_C
-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog
-Dorg.apache.commons.logging.simplelog.log.org.apache.commons.httpclient.wire=ERROR
-XX:+UseConcMarkSweepGC
-XX:+CMSIncrementalMode
-Xmx2560m
-Xms2560m
-XX:NewSize=512M
-XX:MaxPermSize=512m
-XX:PermSize=256M
-XX:+UseCompressedOops
-XX:AutoBoxCacheMax=2048
-Dorg.jboss.boot.log.file=/opt/app/logs/jboss/PRD00_C/boot.log
-Dlogging.configuration=file:/opt/app/jboss-eap-6.0.1/server/PRD00_C/configuration/logging.properties
-jar
/opt/app/jboss/jboss-modules.jar
-mp
/opt/app/jboss/modules
-jaxpmodule
javax.xml.jaxp-provider
org.jboss.as.standalone
-Djboss.home.dir=/opt/app/jboss
-Djboss.server.base.dir=/opt/app/jboss-eap-6.0.1/server/PRD00_C
--server-config=standalone-full-PRD.xml
--properties=file:/opt/app/AgentDesktop/work/jboss/combined.101932939.properties
-Djboss.socket.binding.port-offset=300
-Djboss.server.base.dir=/opt/app/jboss/server/PRD00_C
-Djboss.server.log.dir=/opt/app/logs/jboss/PRD00_C
-Dcom.kana.properties.url=file:/opt/app/AgentDesktop/work/jboss/combined.101932939.properties
-Dcom.gtnet.systemProperties.override.url=file:/opt/app/AgentDesktop/config/PRD//override.properties
-Dcore.home=/opt/app/AgentDesktop
-Denvironment.dir=/opt/app/AgentDesktop/config/PRD
-Denvironment.url=file:/opt/app/AgentDesktop/config/PRD/
-Drelease.id=1
-Dorg.apache.tomcat.util.http.Parameters.MAX_COUNT=1000
-Dorg.jboss.as.logging.per-deployment=false
-b
0.0.0.0
-XX:+CMSClassUnloadingEnabled
控制在Concurrent-Mark-Sweep循环中是否可以卸载类。但是,即使关闭该选项,类 仍然可以在 Full(停止世界)GC 期间卸载。
使用 CMS 收集器可以触发 Full GC,原因是:
- Concurrent mode failure;
- Promotion failure;
- 显式调用
System.gc
(在您的情况下显然已禁用)。
检查 GC 日志是否包含 (concurrent mode failure)
或 (promotion failed)
消息。