当前位置:主页 > 开发者平台 >

某应用偶尔会出现极为频繁的Promotion failed,导致cms gc切换为串行full gc

作者:AG集&#发表时间:2018-09-21

解决过程:
1、从promotion failed的日志来看,应该是在那段时间内内存被消耗光了造成的,因此在promotion failed的时候dump了内存;

2、可惜dump出来的那个内存文件打不开,几次都是如此;

3、还好我们自己定制的jdk版本这个时候发挥了作用,这个版本中有个功能是如果代码中有地方分配了超级大的数组,会打印出堆栈;

4、在某次出问题的时候,我们看到了这样的堆栈信息:

==WARNNING==  allocating large array: thread_id[0x00002aaac2d85800], thread_name[ajp-0.0.0.0-8009-48], array_size[782611408 bytes], array_length[195652847 el
ememts]
        at 亚游平台java.util.Arrays.copyOf(Arrays.java:2734)
        at java.util.ArrayList.ensureCapacity(ArrayList.java:167)
        at java.util.ArrayList.add(ArrayList.java:351)
        at net.sf.json.JSONArray._fromJSONTokener(JSONArray.java:1154)
        at net.sf.json.JSONArray.fromObject(JSONArray.java:147)
        at net.sf.json.util.JSONTokener.nextValue(JSONTokener.java:358)
        at net.sf.json.JSONObject._fromJSONTokener(JSONObject.java:1128)
        at net.sf.json.JSONObject._fromString(JSONObject.java:1317)
        at net.sf.json.JSONObject.fromObject(JSONObject.java:185)
        at net.sf.json.JSONObject.fromObject(JSONObject.java:154)
        at 我们自己的代码...

5、有这个堆栈后就可以知道是由于自己的代码这个地方触发了json创建了一个巨大的array;

6、于是怀疑是我们传给了json一个很大的String,就先在应用层做了个保护,超过一定大小的String就直接抛错;

7、加上了这个保护后还是出问题了;

8、因此怀疑是json内部有bug,导致传了某种格式的String后就会出现死循环什么的;

9、“神”看代码后,构造了一个这样的String s = “{tag:[0,1,”;然后调用JSONObject.fromObject(s),就会OOM;

10、于是修改了json的代码,修复此bug…

本文源自: 环亚娱乐

开发者平台
联系我们