Java反序列化json内存溢出_fastJson与一起堆内存溢出'血案'

FastJson与一起堆内存溢出'血案'

现象

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.SerializeWriter.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内存

image

点开问题1详情

发现这个JSONArray是配置类PersonalityStrengthenConfig#cost字段

你可能感兴趣的:(Java反序列化json内存溢出_fastJson与一起堆内存溢出'血案')