cgbystrom / netty-tools

A collection of tools useful when working with JBoss Netty.
MIT License
259 stars 68 forks source link

Memory usage issue on 4.0.0.Beta1 #15

Closed vovencij closed 11 years ago

vovencij commented 11 years ago

Hi!

There's something wrong with PoolArena in 4.0.0.Beta1.

If I have a simple Http client pipeline initialized like this:

public class HttpClientIntializer extends ChannelInitializer<SocketChannel> {

    public void initChannel(SocketChannel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();
        pipeline.addLast("codec", new HttpClientCodec());
        pipeline.addLast("chunkedWriter", new ChunkedWriteHandler());
        pipeline.addLast("result", new StringResponseHandler());
    }
}

StringResponseHandler being this:

public class StringResponseHandler extends ChannelInboundMessageHandlerAdapter<Object> {
  private String result;

  @Override
  public void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception {
    HttpResponse response = (HttpResponse) msg;
    ByteBuf content = response.getContent();
    result = content.toString(Charset.defaultCharset());
  }

  public String getResult() {
    return result;
  }
}

Now if I set my maxHeap to say -Xmx8m and do a simple GET request then I will get OutOfMemoryError with this stacktrace:

java.lang.OutOfMemoryError: Java heap space
    at io.netty.buffer.PoolArena$HeapArena.newChunk(PoolArena.java:326)
    at io.netty.buffer.PoolArena.allocateNormal(PoolArena.java:149)
    at io.netty.buffer.PoolArena.allocate(PoolArena.java:138)
    at io.netty.buffer.PoolArena.allocate(PoolArena.java:88)
    at io.netty.buffer.PooledByteBufAllocator.newHeapBuffer(PooledByteBufAllocator.java:135)
    at io.netty.buffer.AbstractByteBufAllocator.heapBuffer(AbstractByteBufAllocator.java:73)
    at io.netty.buffer.AbstractByteBufAllocator.heapBuffer(AbstractByteBufAllocator.java:59)
    at io.netty.buffer.AbstractByteBufAllocator.buffer(AbstractByteBufAllocator.java:38)
    at io.netty.handler.codec.ReplayingDecoder.newInboundBuffer(ReplayingDecoder.java:346)
    at io.netty.handler.codec.ReplayingDecoder.newInboundBuffer(ReplayingDecoder.java:267)
    at io.netty.channel.CombinedChannelHandler.newInboundBuffer(CombinedChannelHandler.java:77)
    at io.netty.channel.DefaultChannelHandlerContext.<init>(DefaultChannelHandlerContext.java:290)
    at io.netty.channel.DefaultChannelPipeline.addLast(DefaultChannelPipeline.java:157)
    at io.netty.channel.DefaultChannelPipeline.addLast(DefaultChannelPipeline.java:147)
    at eu.plumbr.agent.http.HttpClientIntializer.initChannel(HttpClientIntializer.java:32)
    at eu.plumbr.agent.http.HttpClientIntializer.initChannel(HttpClientIntializer.java:25)
    at io.netty.channel.ChannelInitializer.channelRegistered(ChannelInitializer.java:70)
    at io.netty.channel.DefaultChannelHandlerContext$1.run(DefaultChannelHandlerContext.java:83)
    at io.netty.channel.DefaultChannelHandlerContext.fireChannelRegistered(DefaultChannelHandlerContext.java:954)
    at io.netty.channel.DefaultChannelPipeline.fireChannelRegistered(DefaultChannelPipeline.java:867)
    at io.netty.channel.AbstractChannel$AbstractUnsafe.register0(AbstractChannel.java:603)
    at io.netty.channel.AbstractChannel$AbstractUnsafe.register(AbstractChannel.java:587)
    at io.netty.channel.SingleThreadEventLoop$1.run(SingleThreadEventLoop.java:73)
    at io.netty.channel.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:259)
    at io.netty.channel.socket.nio.NioEventLoop.run(NioEventLoop.java:312)
    at io.netty.channel.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:110)
    at java.lang.Thread.run(Thread.java:722)

If I'd run the app for example with -Xmx32m and -XX:+HeapDumpOnOutOfMemoryError then I can see in the heap dump that an instance of io.netty.buffer.PoolArena$HeapArena is holding a byte array of 16 megs.

Alpha7 doesn't have this problem.

vovencij commented 11 years ago

Oops. sorry:) This was intended to be posted in netty issues. You can delete it.