fastjson引发的oom事件

问题描述

12月1日的时候 风控系统 线上出现 metaspace OOM


排查过程

  • 查询了背景资料:hotspot 1.8 里面有了metaspace,且修改自定义classloader相关的class的回收机制。当自定义classloader被标记为可以回收的时候,相关的class才能被全部回收。

  • 由于 风控系统 使用了字节码生成动态class技术,所以初步判定为自定义classloader造成了内存泄漏。

  • 因为出现oom的情况下,java的vm参数设置的好,很容易就dump出heap,然后进行分析

  • 放到MAT使用 list object with incoming reference:
    pic1
    明确可以看到有很多的ClazzLoader对象。

  • 找到任意一个实例,去掉weak,soft,phantom类型的reference,留下的如下:
    pic2
    判断为fastjson 引起的内存泄漏。

  • 翻看代码查看哪里fastjson使用了func中的clazz对象:
    pic3
    pic4

  • 竟然是Func执行成功的情况下的 debug的日志 导致了这个问题,虽然这个日志并没有打印出来(debug级别),但是java执行的时候在这里没有lazy的处理。 很巧合的引起了这个问题。


验证复现问题:

使用fastjson的情况:

pic5

  • 通过分析heap可以发现相同的现象:
    pic7
    pic8
    pic9

不使用fastjson的情况:

pic10


结论

fastjson这个库对动态class文件的序列化是存在风险的。