关于sun的Hotspot JVM中的PermGen能否被GC的问题(-XX:+UseConcMarkSweepGC )

关于sun的Hotspot JVM中的PermGen能否被GC的问题

首先要说明的是PermGen的作用,PermGen是在JVM启动时,类和方法的Meta信息被加载到内存,放在PermGen中。
一般来说,该PermGen是不会被GC掉的,但是也要视JDK的版本和GC的策略有所区别。

(1)、在JDK1.5的版本中,缺省的GC策略是不会对PermGen进行GC的,但是如果想要PermGen被GC,可以通过CMS策略来
实施,样例配置如下:
-server -Xms512m -Xmx512m -XX:+UseConcMarkSweepGC -XX:+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled -XX:CMSInitiatingOccupancyFraction=60 -XX:NewSize=256m  -XX:MaxNewSize=256m -XX:PermSize=40m -XX:MaxPermSize=64m -XX:+HeapDumpOnOutOfMemoryError -XX:SurvivorRatio=8

POC如下图:



此处需要注意的是:使用CMS(ConcMarkSweep)策略时,必须有:-XX:+CMSPermGenSweepingEnabled 和-XX:+CMSClassUnloadingEnabled
来配合同时启用,才可以对PermGen进行GC(

实际主要参数为:-XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled  -XX:+CMSPermGenSweepingEnabled

)。而且参数:-XX:+CMSPermGenSweepingEnabled在JDK1.6中是不存在的。
可以通过jconsole中的MBeans=>com.sun.management.HotSpotDiagnostic来验证JVM中的参数。
(2)、在JDK1.6的版本中,缺省的GC策略是不会对PermGen进行GC的,但是如果想要PermGen被GC,可以通过CMS策略来
实施,样例配置如下:
-server -Xms512m -Xmx512m -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled -XX:PermSize=40m -XX:MaxPermSize=64m -XX:+HeapDumpOnOutOfMemoryError

实际主要参数为:-XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled

效果图如下:


 总结:CMS策略可以对PermGen进行GC,但是前提是应用程序停止后能保证其所使用的类完全达到可以被GC的条件,如果某些web应用中配置了listener的话,这些web应用通过应用服务器的web控制台停掉后,其listener并不会停掉,导致该应用所加载的类不会被卸载。因为:listener中的两个方法,contextInitialized()是在Servlet容器启动时执行,而contextDestroyed()是在Servlet容器停止时执行。因此要想让PermGen在应用服务器启动状态下被GC,需要以下两个条件:

(1)、配置CMS策略,如:

 -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled  -XX:+CMSPermGenSweepingEnabled,只是jdk1.6中不需要-XX:+CMSPermGenSweepingEnabled参数;

(2)、所控制的web应用程序,不能配置类似listener之类的线程应用。

你可能感兴趣的:(java内存管理)