编程语言
首页 > 编程语言> > 工作记录:java.lang.OutOfMemoryError: PermGen space问题排查处理

工作记录:java.lang.OutOfMemoryError: PermGen space问题排查处理

作者:互联网

项目上线当天,预计实时用户在线人数 500-1000 人左右,系统网络请求 QPS 预计达到 5000 以上。Linux 服务器性能 16 核 32 G,系统间隔半小时崩溃一次,查看生产环境日志排查系统崩溃原因并修复。

日志分割

将 tomcat 目录下的 conf 目录下 logging.properties 文件 设置 debug 模式。

打印所有请求输出日志时,请求量过大,日志不断在增长造成文件过大,无法精确快速定位问题日志。

通过设置日志按天分割,解决日志过大问题

linux下实现tomcat的日志文件按天分割

设置完成后将当天的服务器日志down到本地,编辑器打开日志并定位到异常信息,异常如下报错信息:

java.lang.OutOfMemoryError: PermGen space

原因分析:

永久代是 HotSot 虚拟机对方法区的具体实现,存放了被虚拟机加载的类信息、常量、静态变量、JIT编译后的代码等。

JDK8 后,元空间替换了永久代,元空间使用的是本地内存,还有其它细节变化:
字符串常量由永久代转移到堆中和永久代相关的 JVM 参数已移除
可能原因有如下几种:

1、在Java7之前,频繁的错误使用String.intern()方法

2、运行期间生成了大量的代理类,导致方法区被撑爆,无法卸载

3、应用长时间运行,没有重启。没有重启 JVM 进程一般发生在调试时

解决方法:

因为该OOM原因比较简单,解决方法有如下几种:

1、检查是否永久代空间或者元空间设置的过小

2、检查代码中是否存在大量的反射操作

3、dump之后通过mat检查是否存在大量由于反射生成的代理类

4、放大招,重启JVM

生产环境的内存情况

使用 jps 命令查看配置了JVM的服务,端口号

jps

查看某个进程(端口号)JVM 的 GC 使用情况

jstat -gc 端口号 刷新时间

jstat -gc 71614 5000

GC 使用情况字符说明

S0C:年轻代中第一个survivor(幸存区)的容量 (字节) 

S1C:年轻代中第二个survivor(幸存区)的容量 (字节) 

S0U:年轻代中第一个survivor(幸存区)目前已使用空间 (字节) 

S1U:年轻代中第二个survivor(幸存区)目前已使用空间 (字节) 

EC:年轻代中Eden(伊甸园)的容量 (字节) 

EU:年轻代中Eden(伊甸园)目前已使用空间 (字节) 

OC:Old代的容量 (字节) 

OU:Old代目前已使用空间 (字节)

MC:方法区容量 (字节) 

MU:方法区已使用空间 (字节)

YGC:从应用程序启动到采样时年轻代中gc次数 

YGCT:从应用程序启动到采样时年轻代中gc所用时间(s) 

FGC:从应用程序启动到采样时old代(全gc)gc次数 

FGCT:从应用程序启动到采样时old代(全gc)gc所用时间(s) 

GCT:从应用程序启动到采样时gc用的总时间(s) 

发现永久代内存使用百分比偏高 MU/MC(83%)

修改元空间的内存大小,将大小设置成原设置的两倍

修改jvm参数

1.查看 catalina.sh文件,未发现设置的参数信息。添加如下配置

JAVA_OPTS="-Xms16005m -Xmx16005m -Xss1024K -XX:MetaspaceSize=200m -XX:MaxMetaspaceSize=512m"

正常增加如上配置即可重启后打开日志查看启动参数,发现未生效

排查是否有覆盖参数的情况,查看bin目录下是否有setenv.sh文件,如果存在则查看内容配置,setenv.sh文件配置如下:

JAVA_OPTS="-Xms16005m -Xmx16005m -Xss512K -XX:MetaspaceSize=200m -XX:MaxMetaspaceSize=256m"

修改成

JAVA_OPTS="-Xms16005m -Xmx16005m -Xss1024K -XX:MetaspaceSize=200m -XX:MaxMetaspaceSize=512m"

重启服务后参数生效,系统崩溃问题解决。

标签:lang,PermGen,java,字节,代中,XX,gc,JVM,日志
来源: https://www.cnblogs.com/sanxingblogs/p/14272346.html