当我们在IDE控制台发现:
说明我们给jvm的持久代设置的值太小,此时你需要打开eclispe 中window->preferences->Java->Installed JRE ,点击右侧的Edit 按钮,在编辑界面中的 “Default VM Arguments ”选项中,将-XX:PermSize及 -XX:MaxPermSize的值加大。
如果你懂jvm性能调优的话,从jstat监控中可以得知其中的关系。以下为实际演示操作:
1,按照如下图步骤将-XX:PermSize及 -XX:MaxPermSize的值修改到足够小,故意造项目启动报错,我设置为32m.然后保存。
2.在IDE中启动tomcat的同时打开dos窗口,使用jps命令获取进程id:(此进程id即为在windows任务管理器-进程中的javaw.exe的进程id)
3.并立即执行jvm监控:
现在对上图来进行分析:
发现PU等于PC的值,并且也等于前面在IDE中设置的-XX:MaxPermSize的值(32768/1024=32m),结合后面的术语能看明白持久代使用的空间已经达到了最大值32m了,故报出了“java.lang.OutOfMemoryError: PermGen space”错误。
另如果发现YGC值特别大的话,那就将-Xmn的值设置大一点(通过-Xmn10m 选项来指定S0C、S1C和EC的总和为10m的),特别注意FGC,尽量使FGC的值不要太大(解决办法:将-Xms及-Xmx的值设置大一点),,因为FGC在垃圾回收期间会检查所有存活的对象,因此会花费比YGC更长的时间。从而让你的应用反应迟钝,因此应该尽量减少FGC. (所有的垃圾收集都是“Stop the World”事件,因为所有的应用线程都会停下来直到操作完成)
一些术语的中文解释:
S0C:年轻代中第一个survivor(幸存区)的容量 (字节)
S1C:年轻代中第二个survivor(幸存区)的容量 (字节)
S0U:年轻代中第一个survivor(幸存区)目前已使用空间 (字节)
S1U:年轻代中第二个survivor(幸存区)目前已使用空间 (字节)
EC:年轻代中Eden(伊甸园)的容量 (字节)
EU:年轻代中Eden(伊甸园)目前已使用空间 (字节)
OC:Old代的容量 (字节)
OU:Old代目前已使用空间 (字节)
PC:Perm(持久代)的容量 (字节)
PU:Perm(持久代)目前已使用空间 (字节)
YGC:从应用程序启动到采样时年轻代中gc次数
YGCT:从应用程序启动到采样时年轻代中gc所用时间(s)
FGC:从应用程序启动到采样时old代(全gc)gc次数
FGCT:从应用程序启动到采样时old代(全gc)gc所用时间(s)
GCT:从应用程序启动到采样时gc用的总时间(s)
VM 开关 | VM 开关描述 |
---|---|
-Xms | 设置JVM启动时堆的初始化大小。 |
-Xmx | 设置堆最大值。 |
-Xmn | 设置年轻代的空间大小,剩下的为老年代的空间大小。 |
-XX:PermGen | 设置永久代内存的初始化大小。 |
-XX:MaxPermGen | 设置永久代的最大值。 |
-XX:SurvivorRatio | 提供Eden区和survivor区的空间比例。比如,如果年轻代的大小为10m并且VM开关是-XX:SurvivorRatio=2,那么将会保留5m内存给Eden区和每个Survivor区分配2.5m内存。默认比例是8。 |
-XX:NewRatio | 提供年老代和年轻代的比例大小。默认值是2。 |