现象
QA同学反映登录不上服务器
排查问题1–日志级别
查看log,发现玩家登录的时候抛出了一个java.lang.OutOfMemoryError
大概代码是向Redis序列化一个PlayerMirror镜像数据,但是在JSON.toJSONString的时候出现了错误.比较清晰,即序列化的时候expandCapacity,内存不足。
又看了一下日志,有好几个OutOfMemoryError,都是类似于用fastjson序列化PlayerMirror报的错误
又仔细看了一下server目录,发现了几个.hprof,说明确实发生了堆内存溢出,因为启动参数增加了’-XX:+HeapDumpOnOutOfMemoryError’
at java.lang.OutOfMemoryError.()V (OutOfMemoryError.java:48)
at com.alibaba.fastjson.serializer.SerializeW
riter.expandCapacity(I)V (SerializeWriter.java:249)复制
-rw------- 1 xx xx 2043416350 Nov 24 11:37 java_pid8068.hprof
-rw------- 1 xx xx 2028797313 Nov 24 11:17 java_pid4671.hprof
-rw------- 1 xx xx 1477222612 Nov 23 23:25 java_pid31563.hprof复制
排查问题2–JVM命令级别
使用了jvm命令初步排查一下问题 jstat -gcutil pid
jstat -gc pid
jmap -histo pid
jmap -heap pid
jstat看到老年代基本已经满了
jmap看到排名前两位的分别是Object[]和char[]
num #instances #bytes class name
----------------------------------------------
1: 146219 741203672 [Ljava.lang.Object;
2: 2842356 639498168 [C复制
排查问题3–专业工具级别
因为了hprof,所以只需要用专业的内存分析工具mat即可 mat#Open Heap Dump,载入后直接出来一个Getting Started Wizard#Leak Suspects Report,即内存泄露的报告,选择finish 两个怀疑的问题:
其中有一个JSONArray的实例就占用了大约700M内存
另外一个是线程的local Variables占用了500M内存
点开问题1详情,发现这个JSONArray是配置类PersonalityStrengthenConfig#cost字段,仔细看一下这