Netty HashedWheelTimer过多导致内存泄漏的排错
来源:互联网 发布:centos ed2k下载工具 编辑:程序博客网 时间:2024/04/27 17:02
系统环境:
CentOS release 5.6 (Final)
Netty 3.6.5 final
发现问题:
在一次压力测试中,发现Netty Based服务器连上4500+的clients就开始一直FullGC。
解决问题:
GC日志:
- 2013-07-01T09:24:52.328+0800: 227629.120: [Full GC [PSYoungGen: 116544K->112471K(233024K)] [ParOldGen: 699071K->699071K(699072K)] 815615K->811543K(932096K) [PSPermGen: 15071K->15056K(21248K)], 0.6043590 secs] [Times: user=2.34 sys=0.00, real=0.60 secs]
- 2013-07-01T09:24:52.961+0800: 227629.753: [Full GC [PSYoungGen: 116544K->112514K(233024K)] [ParOldGen: 699071K->699071K(699072K)] 815615K->811586K(932096K) [PSPermGen: 15056K->15056K(21248K)], 0.6133040 secs] [Times: user=2.37 sys=0.00, real=0.61 secs]
看出来年老代已经腾不出空间了。结果很明显,有对象导致了内存泄漏。
- jmap -histo XXXX
查看堆使用情况
- num #instances #bytes class name
- ---------------------------------------------
- 1: 10252320 410092800 org.jboss.netty.util.internal.ConcurrentIdentityHashMap$Segment
- 2: 10332783 330649056 java.util.concurrent.locks.ReentrantLock$NonfairSync
- 3: 10252320 328462016 [Lorg.jboss.netty.util.internal.ConcurrentIdentityHashMap$HashEntry;
- 4: 2563074 123027552 org.jboss.netty.util.internal.ConcurrentIdentityHashMap
- 5: 2563072 123027456 org.jboss.netty.util.internal.ConcurrentIdentityHashMap$KeyIterator
- 6: 2563074 82018464 [Lorg.jboss.netty.util.internal.ConcurrentIdentityHashMap$Segment;
- 7: 2563072 41009152 org.jboss.netty.util.MapBackedSet
- 8: 2563072 41009152 org.jboss.netty.util.internal.ConcurrentIdentityHashMap$KeySet
- 9: 258183 12392784 org.jboss.netty.util.HashedWheelTimer$HashedWheelTimeout
看第一行,有10252320 个 org.jboss.netty.util.internal.ConcurrentIdentityHashMap$Segment 对象!
同时发现cpu的占用非常平凡
于是查看线程情况,看到很多类似下面的timer线程:
- jstack XXX
- "Hashed wheel timer #9086" prio=10 tid=0x00002aab886a7000 nid=0xe9f waiting on condition [0x00002aaba4380000]
- java.lang.Thread.State: TIMED_WAITING (sleeping)
- at java.lang.Thread.sleep(Native Method)
- at org.jboss.netty.util.HashedWheelTimer$Worker.waitForNextTick(HashedWheelTimer.java:504)
- at org.jboss.netty.util.HashedWheelTimer$Worker.run(HashedWheelTimer.java:402)
- at org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:108)
- at java.lang.Thread.run(Thread.java:722)
发现很多timer线程,足足有5006个。
思考:
测试压了5000个链接,也就是说timer/channel。可能这两者有关联,先解决timer问题。
查看new HashedWheelTimer的代码,发现有一处代码在每次连接时new了一个HashedWheelTimer,但是没有使用,fix it。(当然过程稍微复杂,没写的这么简单)
接着想线程跟内存泄漏的联系,看源码最实际,于是发现了这些timer是怎么把内存吃掉的。
默认每个Wheel有512个槽位,每个槽是一个MapBackedSet,每个MapBackedSet包含一个ConcurrentIdentityHashMap,每个ConcurrentIdentityHashMap默认大小为4。
- public HashedWheelTimer(
- ThreadFactory threadFactory, long tickDuration, TimeUnit unit) {
- this(threadFactory, tickDuration, unit, 512);
- }
- for (int i = 0; i < wheel.length; i ++) {
- wheel[i] = new MapBackedSet<HashedWheelTimeout>(
- new ConcurrentIdentityHashMap<HashedWheelTimeout, Boolean>(16, 0.95f, 4));
- }
512 × 5000 × 4 = 10240000
很接近于10252320这个数字。OK,所有问题都解决了~!
- Netty HashedWheelTimer过多导致内存泄漏的排错
- Netty HashedWheelTimer过多导致内存泄漏的排错
- nginx子请求数量过多导致的内存泄漏
- netty HashedWheelTimer
- Netty 的内存泄漏问题
- 导致内存泄漏的原因
- ThreadLocal 导致的内存泄漏
- InputMethodManager导致的内存泄漏
- netty定时器HashedWheelTimer
- netty时间轮HashedWheelTimer
- Netty bytebuf 内存泄漏
- VarFormat的不正确使用导致内存泄漏
- 导致IE浏览器内存泄漏的研究
- cvLoadImage导致内存泄漏的解决
- simple_html_dom使用不当导致的内存泄漏
- _com_util::ConvertBSTRToString 方法导致的内存泄漏
- 使用cvLoadImage导致内存泄漏的解决方法
- 一次dialog导致的内存泄漏
- C++运算符优先级
- atoi,atol,strtod,atof
- java获取当前运行路径并读取properties文件
- HP LE2001W电源键解锁
- 基于80x86的Linux的分段和分页机制
- Netty HashedWheelTimer过多导致内存泄漏的排错
- 内存对齐方式的总结 如何计算结构体所占内存的大小
- Can you install the Xcode 5 Developer Preview in parallel with Xcode 4.6.2?
- 基于行块分布函数的通用网页正文抽取:线性时间、不建DOM树、与HTML标签无关
- uva 400 Unix ls
- HTTP协议与HTML表单(再谈GET与POST的区别)
- SVM
- OCP-1Z0-053-V12.02-323题
- Objective-C 宏定义 总结