Netty内存泄露

来源:互联网 发布:影楼照片后期制作软件 编辑:程序博客网 时间:2024/05/07 18:51
在测试中发现,当不停的开关Netty的NioClientSocketChannelFactory(比如大量连接失败重连等情况下),存在Direct Memory泄露。
测试代码:
Java代码  收藏代码
  1. for (int i = 0; i < Integer.MAX_VALUE; i ++) {  
  2.     ChannelFactory channelFactory = new NioClientSocketChannelFactory(  
  3.             Executors.newCachedThreadPool(), Executors.newCachedThreadPool());  
  4.     Bootstrap bootstrap = new ClientBootstrap(channelFactory);  
  5.     bootstrap.setPipelineFactory(new ChannelPipelineFactory() { ... });  
  6.     ChannelFuture future = bootstrap.connect(serverAddress);  
  7.     future.await(); // or future.addListener(new ChannelFutureListener() { ... });   
  8.     Channel channel = future.getChannel();  
  9.     channel.close();  
  10.     // FIXME NioClientSocketChannelFactory direct buffer memory leak  
  11.     channelFactory.releaseExternalResources(); // or bootstrap.releaseExternalResources();  
  12. }  
for (int i = 0; i < Integer.MAX_VALUE; i ++) {
    ChannelFactory channelFactory = new NioClientSocketChannelFactory(
            Executors.newCachedThreadPool(), Executors.newCachedThreadPool());
    Bootstrap bootstrap = new ClientBootstrap(channelFactory);
    bootstrap.setPipelineFactory(new ChannelPipelineFactory() { ... });
    ChannelFuture future = bootstrap.connect(serverAddress);
    future.await(); // or future.addListener(new ChannelFutureListener() { ... }); 
    Channel channel = future.getChannel();
    channel.close();
    // FIXME NioClientSocketChannelFactory direct buffer memory leak
    channelFactory.releaseExternalResources(); // or bootstrap.releaseExternalResources();
}


抛出的异常信息:
Java代码  收藏代码
  1. Caused by: java.lang.OutOfMemoryError: Direct buffer memory  
  2. at java.nio.Bits.reserveMemory(Bits.java:633)  
  3. at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:95)  
  4. at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:288)  
  5. at org.jboss.netty.channel.socket.nio.SocketSendBufferPool$Preallocation.<init>(SocketSendBufferPool.java:159)  
  6. at org.jboss.netty.channel.socket.nio.SocketSendBufferPool.<init>(SocketSendBufferPool.java:46)  
  7. at org.jboss.netty.channel.socket.nio.NioWorker.<init>(NioWorker.java:84)  
  8. at org.jboss.netty.channel.socket.nio.NioClientSocketPipelineSink.<init>(NioClientSocketPipelineSink.java:74)  
  9. at org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory.<init>(NioClientSocketChannelFactory.java:135)  


询问了Netty的作者Trustin Lee:
Trustin Lee 写道

ChannelFactories are never meant to be created many times. JVM is poor at managing direct buffers, so there's no way to fix this problem without using JNI. One possible workaround would be call System.gc() explicitly, but I'm not sure it's a reliable workaround.


看起来是JVM对direct buffer管理的问题,Netty估计也没有直接的办法解决,
只能静态化ChannelFactory规避,以减少泄露:
Java代码  收藏代码
  1. private static final NioClientSocketChannelFactory channelFactory = ...;  
0 0
原创粉丝点击