背景:
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,所有问题都解决了~!
相关推荐
在压力测试阶段,发现 Gateway 有内存泄漏问题,具体表现为:当启动一台 Gateway 和一台对应的下游应用服务时,在压力测试期间,发现 Gateway 的内存会暴涨,并由于超过限制的最大内存导致容器挂掉。 内存泄漏问题...
本jar包为最新的netty-all-4.1.29c.jar 可导入直接用 Netty 是一个利用 Java 的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的 API 的客户端/服务器框架。 Netty 是一个广泛使用的 Java 网络编程框架...
此外,还会涉及ByteBuf,这是Netty提供的高效内存管理工具,用于替代Java的ByteBuffer,提供更友好的API和更好的性能。 Netty的案例实战部分可能会涵盖常见网络协议的实现,如HTTP、HTTPS、FTP、WebSocket等,这些...
3. **ByteBuf**:Netty提供了自己的ByteBuf类,作为缓冲区,它比Java的ByteBuffer更易用且高效,支持直接内存和堆内存操作,避免了频繁的内存复制。 4. **零拷贝**:Netty通过使用FileRegion实现零拷贝,减少了CPU...
此外,Netty的API设计易于理解和使用,使得开发者可以专注于业务逻辑,而无需过多关注底层网络通信的复杂性。 该压缩包中的"netty-4.1.16.Final"可能包含以下组件: 1. `netty-all`: 所有模块合并的jar包,便于一次...
此外,Netty的ByteBuf类是高效内存管理的关键,它提供了缓冲区的读写操作,避免了不必要的数据拷贝。 在高级特性部分,书籍会涉及Netty的编解码器,如LineBasedFrameDecoder用于处理以换行符分隔的协议,以及...
《跟闪电侠学Netty:Netty即时聊天实战与底层原理》是一本深入浅出的Netty技术指南,旨在帮助读者掌握Netty框架,并利用它实现即时聊天应用,同时理解其底层工作原理。Netty是Java领域的一款高性能、异步事件驱动的...
1. **NIO(非阻塞I/O)基础**:Netty 基于 Java NIO (Non-blocking I/O) 构建,提供了更高效的 I/O 处理方式,通过 Channel 和 Selector 实现多路复用,可以同时处理大量并发连接。 2. **ByteBuf**:Netty 提供了 ...
除此之外,Netty还提供了强大的心跳检测机制,可以防止因网络延迟或故障导致的连接僵死。其优雅的关闭机制也能确保在系统关闭时,所有正在处理的连接都能得到妥善处理。 总之,《深入浅出Netty》会带你深入理解...
7. **线程模型**:Netty的EventLoopGroup负责管理和调度事件循环,确保线程资源的合理使用,避免了多线程同步的复杂性。 8. **零拷贝**:Netty通过直接将数据从网络缓冲区传递到用户缓冲区,或者反之,实现了零拷贝...
6. **线程模型**:Netty的EventLoop和EventLoopGroup机制确保了线程资源的有效利用,避免了线程过多导致的资源浪费。 7. **错误处理**:Netty提供了完善的异常处理机制,能有效地捕获和处理网络通信中的各种异常,...
Netty 4.1.19.Final 版本包含了多个优化和改进,例如更好的内存管理、性能提升以及对新协议的支持。其中,ByteBuf是Netty自定义的缓冲区,它比Java的ByteBuffer更高效,支持零拷贝,有助于减少内存开销和提高网络I/O...
- Netty 的 ByteBuf 提供了高效的内存管理,避免了频繁的字节数组拷贝。 2. **WebSocket 协议** - WebSocket 协议通过 HTTP/HTTPS 协议握手建立连接,之后即可在连接上进行双向数据传输,无需重复的 HTTP 请求/...
Netty基础,用于学习Netty,参考黑马程序员的netty教程
《深入浅出Netty_netty5.0_》是针对Netty 5.0版本的一本详细教程,旨在帮助读者理解并熟练运用这一强大的网络编程框架。Netty是一个开源的Java框架,它为开发高效、稳定、可扩展的网络应用提供了全面的支持。在本文...
总结,利用 Netty 实现文件传输是一个涉及网络编程、多线程、I/O 操作以及内存管理的综合实践。通过 Netty 的强大功能,我们可以构建高效、可靠的文件传输系统。在实际应用中,还需要考虑到性能优化、安全性以及异常...
- **安全性**:提供了更好的内存管理机制,避免了内存泄漏等问题。 具体来说,Netty中有两种主要的`ChannelBuffer`实现: 1. **HeapChannelBuffer**:这是一种基于堆内存的实现方式,即缓冲区位于Java虚拟机的堆...
1. **Netty3版本升级遭遇内存泄漏案例**:该案例描述了一个项目在从旧版本升级到Netty3时遇到的内存泄漏问题。通过对内存使用情况进行分析,最终定位到了泄漏源头,并提出了相应的解决方案。 2. **Netty3版本升级...
Netty 是一个高性能、异步事件驱动的网络应用程序框架,常用于开发高并发、低延迟的网络服务。SpringMVC 是 Spring 框架的一部分,主要用于构建 Web 应用程序,提供模型-视图-控制器(MVC)的架构模式。整合 Netty ...