background image

两个

OOM Cases 的排查经历

分享一下两个

OOM Cases 的查找过程,一个应用是 Native OOM;另外一个应用其实没有

OOM,只是每隔一段时间就会出现频繁 FGC 的现象,OOM 的查找已经具备了不错的工具,
但有些时候还是会出现很难查的现象,希望这两个排查过程的分享能给需要的同学带来一
些帮助。

Native OOM 的排查 Case
之前的几个

PPT 里我都说到了,目前查找 Native OOM 最好的方法就是用 google perftools

了,于是挂上

google perftools,等待应用再次 native oom,很幸运,两天后,应用就再次

native oom 了,于是分析 crash 之前那段时间谁在不断的分配堆外的内存,pprof 看到的结果
主要是

java.util.Inflater 造成的,由于之前已经碰到过类似的 case,知道如果使用了

Inflater,但不显式的调用 Inflater.end 的话,确实会造成这个现象。
于是剩下的问题就是找出代码里什么地方调用了

Inflater,这种时候 btrace 这个神器就可以

发挥作用了,一个简单的

btrace 脚本:

?

1
2
3
4
5
6
7
8
9
10
11
12
13

import

 

static

 com.sun.btrace.BTraceUtils.*;

import

 com.sun.btrace.annotations.*;

 
@BTrace 

public

 

class

 Trace{

   @OnMethod(
      clazz="java.util.zip.Inflater",
      method="/.*/"
   )
   

public

 

static

 

void

 traceExecute(@ProbeMethodName String methodName){

     println(concat("who call Inflater.",methodName));
     jstack();
   }
}

执行后很快就找到了代码什么地方调用了

Inflater,于是加上了显式的调用 Inflater.end,搞

定收工。

偶尔频繁

FGC 的排查 Case

这个

Case 就没上面的那个那么顺利了,查了有接近一个月才查出最终的原因。

当这个应用出现频繁

FGC 时,dump 了内存,用 MAT 分析后,看到内存被消耗完的原因是

由于几个线程内的

ThreadLocalMap 中有大量的数据,ThreadLocal 中消耗最多内存的主要