线上使用的公共转发服务崩溃,因为运维部门部署服务会再服务崩溃后自动重启。每隔半个小时服务会进行重启一次。
首先第一时间,进行监控的报警,发现报警以后。查看监控平台中服务器的指标,发现内存在半个小时内会清空一次,然后又慢慢涨上来达到一个平稳的状态,这个时候,就怀疑是不是因为内存不够导致了,然后出现了OOM内存溢出,CG异常。通过监控平台的指标看到确实可以确认就是这个原因了。至于是什么原因导致的,我们进一步的进行排查。
第一个:排查JVM新生代,老年代具体的内存使用和分配情况。发现堆的空间申请比物理机内存还要大。这个时候就已经确定问题了。可能是配置的堆大小没有设置好。
内存溢出:申请的内存超出了JVM能提供的内存大小,此时称之为溢出。
Java heap space异常(java.lang.OutOfMemoryError: Java heap space): 这是最常见的类型,表示Java堆内存不足,无法为新对象分配空间。
物理机的配置:8G。4核。
修改前:
ENV JAVA_OPTS “-Duser.timezone=GMT+08 -server -Xms15360m -Xmx15360m -XX:+UseContainerSupport -XX:NewSize=10240m -XX:MaxNewSize=10240m -XX:MaxDirectMemorySize=960m -XX:MetaspaceSize=480m -XX:MaxMetaspaceSize=960m -XX:+UseG1GC -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=1024M -XX:+ExplicitGCInvokesConcurrent -XX:-UseGCOverheadLimit -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -javaagent:/usr/local/apm_agent/apm.agent.bootstrap.jar -Xloggc:/data/logs/skynet-
D
A
O
K
E
A
P
P
U
K
/
{DAOKEAPPUK}/
DAOKEAPPUK/{DAOKEAPPUK}_gc.log -Dapm.applicationName=
D
A
O
K
E
A
P
P
U
K
−
D
a
p
m
.
a
g
e
n
t
I
d
=
{DAOKEAPPUK} -Dapm.agentId=
DAOKEAPPUK−Dapm.agentId={HOST}-
D
A
O
K
E
I
D
−
D
a
p
m
.
e
n
v
=
{DAOKEID} -Dapm.env=
DAOKEID−Dapm.env={DAOKEENVTYPE}”
这里可以看到,设置的堆开始值15个G,最大值也是15G。堆新生代10G。因为服务器中要运行java服务和其他的一些内容都要使用到内存。当jvm的新生代一直在生产对象,但是又没有办法回收的时候,新生代就持续增加,当到达了一定的量。此时java服务在运行中又生产了新的对象去申请内存,这个时候,内存已经满了,申请不到内存,就发生了内存溢出了。无法给新的对象分配空间了。
修改后:
ENV JAVA_OPTS “-Duser.timezone=GMT+08 -server -Xms4096m -Xmx8192m -XX:+UseContainerSupport -XX:NewSize=2048m -XX:MaxNewSize=2048m -XX:+UseG1GC -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=1024M -XX:+ExplicitGCInvokesConcurrent -XX:-UseGCOverheadLimit -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -javaagent:/usr/local/apm_agent/apm.agent.bootstrap.jar -Xloggc:/data/logs/skynet-
D
A
O
K
E
A
P
P
U
K
/
{DAOKEAPPUK}/
DAOKEAPPUK/{DAOKEAPPUK}_gc.log -Dapm.applicationName=
D
A
O
K
E
A
P
P
U
K
−
D
a
p
m
.
a
g
e
n
t
I
d
=
{DAOKEAPPUK} -Dapm.agentId=
DAOKEAPPUK−Dapm.agentId={HOST}-
D
A
O
K
E
I
D
−
D
a
p
m
.
e
n
v
=
{DAOKEID} -Dapm.env=
DAOKEID−Dapm.env={DAOKEENVTYPE}”
修改以后就一切正常了。