成长的原因
>很多类,特别是JSP。
>很多静态变量。
>有一个类加载器泄漏。
对于那些不知道,这里是一个简单的方式来思考PremGen如何填补。年轻的基因没有足够的时间让事情过期,所以他们被移动到旧世纪的空间。 Perm Gen保存了Young和Old Gen中对象的类。当Young或Old Gen中的对象被收集并且该类不再被引用时,它从Perm Gen中被卸载。如果Young和旧Gen不会得到GC’d,然后也不是Perm Gen,一旦它填满它需要一个完全停止的世界GC。详情请参阅Presenting the Permanent Generation。
切换到CMS
我知道你使用G1,但如果你切换到并发标记清除(CMS)低暂停收集器-XX:UseConcMarkSweepGC,尝试通过添加-XX:CMSClassUnloadingEnabled启用类卸载和永久生成收集。
隐藏的Gotcha’
如果使用JBoss,则RMI / DGC的gcInterval设置为1分钟。 RMI子系统每分钟强制一次完整的垃圾回收。这反过来迫使促进,而不是让它收集在年轻一代。
你应该改变这至少1小时,如果不是24小时,为了GC做适当的集合。
-Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000
每个JVM选项的列表
要查看所有选项,请从cmd行运行此选项。
java -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -version
如果你想看看JBoss是如何使用的,那么你需要添加以下到你的standalone.xml。您将获得每个JVM选项及其设置的列表。注意:它必须在您要查看的JVM中才能使用它。如果你在外部运行它,你将不会看到JBoss正在运行的JVM中发生了什么。
set "JAVA_OPTS= -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal %JAVA_OPTS%"
当我们只对修改的标志感兴趣时,有一个快捷方式。
-XX:+PrintcommandLineFlags
诊断
使用jmap来确定哪些类正在消耗永久性生成空间。输出将显示
>类装载器
>类的数量
>字节
>父加载器
>活着/死亡
>类型
>总计
jmap -permstat JBOSS_PID >& permstat.out
这些设置对我工作,但取决于您的系统如何设置和您的应用程序正在做什么将决定它们是否适合您。
> -XX:SurvivorRatio = 8 – 将幸存者空间比设置为1:8,导致更大的幸存者空间(比率越小,空间越大)。 SurvivorRatio是Eden空间相对于一个幸存者空间的大小。更大的幸存者空间允许短寿命的对象在更年轻的一代死亡更长的时间段。
> -XX:TargetSurvivorRatio = 90 – 允许占用90%的幸存者空间,而不是默认的50%,允许更好地利用幸存者空间内存。
> -XX:MaxTenuringThreshold = 31 – 防止从年轻人到老一代的过早晋升。允许短命的对象在年轻一代中死亡的时间更长(因此,避免晋升)。此设置的后果是,由于要复制的附加对象,较小的GC时间可能会增加。该值和幸存者空间大小可能需要被调整,以平衡幸存者空间与将要长时间存活的终止对象之间的拷贝的开销。 CMS的默认设置为SurvivorRatio = 1024和MaxTenuringThreshold = 0,这会导致清除的所有幸存者被提升。这可能对收集终止代的单个并发线程施加很大压力。注意:与-XX:UseBiasedLocking一起使用时,此设置应为15。
> -XX:NewSize = 768m – 允许指定初始年轻代尺寸
> -XX:MaxNewSize = 768m – 允许规定最大年轻代尺寸
这里有一个更广泛的JVM options列表。