Java程序持续Full GC的处理经历(转)
来源:互联网 发布:php社区源码 编辑:程序博客网 时间:2024/05/22 07:44
1. 发现问题
最近在检查爬虫程序运行情况的时候发现采集速度非常慢,查看cpu占用率的时候发现有一个内核一直是100%,按理说多线程的程序不应该会出现这样的情况。第一反应就是用jstack -l [pid]把线程dump出来查看栈情况,但没发现什么异常。然后就考虑用jmap -heap [pid]把内存使用情况打印出来看看,奇怪的是出现好几次连接不上的情况,等打印出来发现居然旧生代已经满了。把内存调大,发现过不了一会又是这样,确实非常蹊跷。
2. 深入调查
看来问题比较棘手,只好用更细致的方式去分析了。一方面打开了GC日志,同时在运行时用jstat -gcutil [pid] 1000来跟踪GC情况。现象很奇怪,旧生代空间缓慢增长,但突然新生代内存占用100%,旧生代紧接着也变成100%,然后就一直处于full gc,但内存丝毫没有减少,整个过程持续了5分钟。(截图忘记保存了,悲剧...)
看现象就是对象爆炸,但程序已经运行很久了,如果有这么严重的bug应该早就发现了。严谨起见,我用jmap -histo [pid]把程序的对象情况打印出来,结果非常惊讶。
- num #instances #bytes class name
- ---------------------------------------------
- 1: 30110820 1204432800 org.jsoup.parser.ParseError
- 2: 33076 156025088 [Ljava.lang.Object;
- 3: 68836 98796360 [C
系统中居然出现那么多ParserError对象,这个是程序中用到的一个Jsoup开源包里面的东西。看命名像是一个Exception,但查看源码时才发现居然是一个Class。至于这个东西从哪里蹦出来的呢?!我在现象出现的时候打印了下线程栈信息,果然定位到了生成这个对象的那个位置。
在源码中找到相应的实现,主要是调用了这样一个方法:
- private boolean trackErrors = true;
- ......
- void error(TokeniserState state) {
- if (trackErrors)
- errors.add(new ParseError("Unexpected character in input", reader.current(), state, reader.pos()));
- }
这里有一个trackErrors做开关,默认是true,但找了一下,居然没有最外层的方法去控制它,而errors这个对象也是一个private值,没有任何调用,可能是作者自己测试用的。
3. 问题的处理
原因调查清楚,处理就很简单了。直接把源码中trackErrors的默认值改成false,再确认了一下其他相关调用的方法,然后重新编译打包,把原始包替换了。
4. 总结
找问题还是要先分析出可能的原因,然后借用工具去定位问题,很多时候数据比经验更可靠。
- Java程序持续Full GC的处理经历(转)
- 详解Java GC的工作原理+Minor GC、Full GC
- 用Java获取full GC的次数
- (转)FULL GC分析过程分享
- 【java基础】Minor GC、Major GC和Full GC之间的区别
- Java垃圾回收之Minor GC和Major GC(或称为Full GC)
- 案例分析:java中substring引发的Full gc
- Java -- ExecutorService线程池触发的Full GC问题排查
- Java深入 - 触发Full GC执行的情况
- java nio多线程引起的full gc问题
- java-jvm-full gc频繁的分析及解决
- 记一次惨痛的java服务器full gc.......经过
- Major GC和Full GC的区别
- Major GC和Full GC的区别
- Minor GC、Major GC和Full GC之间的区别(收集于网络)
- Full gc的触发条件
- full GC触发的条件
- 触发full GC的情况
- 百度移动开发笔试题
- java中的jar打包成可执行文件,可以避免在linux中的java程序运行时内存剧增现象
- 运行jar 提示 Failed to load Main-Class manifest attribute from
- 去除ArrayList集合中的重复元素
- VC技术内幕笔记
- Java程序持续Full GC的处理经历(转)
- 面试题整理-合并数组
- 将自定义对象作为元素存到ArrayList集合中,并去除重复元素
- 对象数组或list排序及Collections排序原理
- java中的Iterator和Iterable 区别 ,以及为么要有iterable接口
- 浅谈大型网站的算法和架构(1)
- 关于函数strtok和strtok_r的使用要点和实现原理
- OSGi的EventAdmin
- UNIX文件结构(转自UNIX/AIX操作系统基础教程)