因为应用使用了OSGi框架,《深入理解JAVA虚拟机》中对使用OSGi时可能产生的方法区溢出有所描述
第一部分:
第二部分
可见,OSGi会动态生成大量Class,在OSGi中,即使是同一个类文件,被不同的加载器加载也会视为不同的类。
因此方法区在默认比较小的情况下,可能会溢出,实际上也确实遇到了
我计划的解决方法
1.确认Linux物理内存大小,free -h
2.确认JDK版本,已确认是64位的 JDK1.6
hotspot1.6中,整个JVM堆内存大小=Xmx=年轻代大小 + 老年代大小。持久代(也就是方法区)要另外算,默认大小是64M(64位JVM由于指针膨胀,默认是85M)
永久代是一片连续的堆空间,在JVM启动之前通过在命令行设置参数-XX:MaxPermSize来设定永久代最大可分配的内存空间,当JVM加载的类信息容量超过了参数-XX:MaxPermSize设定的值时,应用将会报OOM的错误
3.修改启动脚本
java -Xmx256m -XX:PermSize=128M -XX:MaxPermSize=256MB TestData.java
4.
// 查看当前机器上所有运行的java进程名称与pid(进程编号) jps -l // 显示指定的jvm进程所有的属性设置和配置参数 jinfo pid // 查询某个pid进程对应的应用程序内存占用情况 jmap -heap pid // 显示进程详情 jstack pid // jstat: 可以实时监测系统资源占用与jvm运行情况 (位于”jdk_home/bin”目录下) jstat -class -t 5940