tomcat7 session共享集群导致的FullGC问题

告警通知:北京二E 2020-08-02 14:10UHost(ID:****)CPU使用率(81%)>=80%(默认项目)

java version "1.8.0_11"

处理过程

1.使用top查看进程的CPU使用情况

[root logs]# top
top - 14:34:51 up 513 days,  4:42,  3 users,  load average: 3.27, 2.81, 2.34
Tasks: 147 total,   1 running, 146 sleeping,   0 stopped,   0 zombie
Cpu(s): 59.8%us,  0.2%sy,  0.0%ni, 40.0%id,  0.0%wa,  0.0%hi,  0.1%si,  0.0%st
Mem:  16270528k total, 10517928k used,  5752600k free,   178872k buffers
Swap:        0k total,        0k used,        0k free,  1333952k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                                                    
8817 root      20   0 7867m 3.9g  18m S 235.5 25.0 929:15.66 java                                                                                                                                       
16102 root      20   0 7860m 3.9g  14m S  4.3 24.9 743:39.72 java                                                                                                                                        
21631 root      20   0 15032 1276  944 R  0.3  0.0   0:00.06 top                                                                                                                                         
    1 root      20   0 19368 1232  912 S  0.0  0.0   0:01.55 init      

可以看到是pid为8817的进程占用了CPU。

2.先用jstat -gcutil (查看GC汇总信息),看下对应的堆内存各部分的使用量

[root@ logs]# jstat -gcutil 8817
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT   
  0.00   0.00 100.00 100.00  55.48  79.70  72824 1046.497  1339 3559.981 4606.479

显示列名 具体描述
S0 年轻代中第一个survivor(幸存区)已使用的占当前容量百分比
S1 年轻代中第二个survivor(幸存区)已使用的占当前容量百分比
E 年轻代中Eden(伊甸园)已使用的占当前容量百分比
O old代已使用的占当前容量百分比
M 元数据空间使用比例
CCS 压缩使用比例
YGC 从应用程序启动到采样时年轻代中gc次数
YGCT 从应用程序启动到采样时年轻代中gc所用时间(s)
FGC 从应用程序启动到采样时old代(全gc)gc次数
FGCT 从应用程序启动到采样时old代(全gc)gc所用时间(s)
GCT 从应用程序启动到采样时gc用的总时间(s)

可以看到
年轻代Eden区和老年代的使用容量都是100%

补充个知识点:
大多数情况下,对象在新生代Eden区分配。(大对象会直接在老年代分配,使用参数进行设置)当Eden区分配足够的空间进行分配时,就会触发MinorGc(新生代GC)。将超过GC年龄的对象移动到老年代中。

大致就能断定是对象Eden区分配内存时容量不够触发了GC,而导致的GC停顿。
但是由于新生代和老年代的使用都是100%而对象又全都在被使用。所以无法回收内存。
导致一直GC,一直停顿。。。
问题找到了,这没办法了。直接重启服务,毕竟没有什么是重启不能解决的。
但是在重启之前先做一件事情。把堆内存的快照dump下来,找找为什么2G的内存都被用完了,还无法回收。。。

3.使用 jmap -dump:live 生成快照

jmap -dump:live,format=b,file=8817.hprof 8817
使用scp 远程上传文件到跳板机

4.安装MemoryAnalyzer工具

链接:https://pan.baidu.com/s/1QFE7SMA_j27uMaFKeTlswg
提取码:tjqq

解压后修改.ini配置文件。
tomcat7 session共享集群导致的FullGC问题_第1张图片
我的dump文件是2G,给了4G内存
tomcat7 session共享集群导致的FullGC问题_第2张图片

5.分析dump

友情提示:分析前把dump文件单独放到一个文件夹中,分析过程中会产生一系列的文件。
tomcat7 session共享集群导致的FullGC问题_第3张图片

运行MemoryAnalyzer.exe,File–>open File 打开dump文件
tomcat7 session共享集群导致的FullGC问题_第4张图片
tomcat7 session共享集群导致的FullGC问题_第5张图片
打开之后是这样的
tomcat7 session共享集群导致的FullGC问题_第6张图片
在Memory Analyzer的诊断中也给了我们提醒:
tomcat7 session共享集群导致的FullGC问题_第7张图片
大概是说:LazyReplicatedMap占用了1,289,695,768 bytes 约为1.2GB。
点Details可以查看详情
tomcat7 session共享集群导致的FullGC问题_第8张图片

6.查找原因

查找 LazyReplicatedMap,出来的都是tomcat集群相关的答案,正好项目中确实用到了tomcat集群,应该是tomcat的集群问题,导致的session占用了太多的内存
tomcat7 session共享集群导致的FullGC问题_第9张图片
tomcat7 session共享集群导致的FullGC问题_第10张图片

7.替换tomcat7 session集群方案

使用redis 存储session方式,替代tomcat自身的集群

8.问题解决过程中参考的文章

内存管理工具Memory Analyzer的使用
tomcat集群实现源码级别剖析

你可能感兴趣的:(jvm笔记)