Java Netty 3.3.1.Final,DynamicChannelBuffer.java:75,无限循环,一个bug?

时间:2012-04-02 09:56:02

标签: java infinite-loop netty

我正在使用Netty 3.3.1.Final来满足我们对自定义服务器的需求。 我们的执行在无限循环中被阻止: org.jboss.netty.buffer.DynamicChannelBuffer.ensureWritableBytes(DynamicChannelBuffer.java:75)

使用debuger进入代码将显示以初始值开头的无限循环: minNewCapacity = 2147483647 newCapacity = 256
(二进制1111111111111111111111111111111)
(二进制0000000000000000000000100000000)

原因是<< =运算符将导致newCapacity达到最大值1000000000000000000000000000000,并且在下一步中newCapacity将永远变为0。

这部分代码缺少文档,所以我不能深入分析,但我想知道这是否是一个已知问题,如果我可以使用另一个版本的netty?

@Override
    public void ensureWritableBytes(int minWritableBytes) {
        if (minWritableBytes <= writableBytes()) {
            return;
        }

        int newCapacity;
        if (capacity() == 0) {
            newCapacity = 1;
        } else {
            newCapacity = capacity();
        }
        int minNewCapacity = writerIndex() + minWritableBytes;
        //INFINITE LOOP HERE
        while (newCapacity < minNewCapacity) {
            newCapacity <<= 1;
        }

        ChannelBuffer newBuffer = factory().getBuffer(order(), newCapacity);
        newBuffer.writeBytes(buffer, 0, writerIndex());
        buffer = newBuffer;
    }

感谢您的帮助,

雷诺


添加评论:

这是导致minNewCapacity如此之高的方法,因为它会导致巨大的内存缓冲... org.jboss.netty.ReplayingDecoderBuffer.readableBytes(ReplayingDecoderBuffer.java:301)

public int readableBytes() {
        if (terminated) {
            return buffer.readableBytes();
        } else {
            return Integer.MAX_VALUE - buffer.readerIndex();
        }
    }

添加评论2012/04/13

我最终决定不使用ReplayingDecoder,因为它会导致一些非常奇怪的行为。 特别是,在decode()方法中使用ChannelBuffer参数的mark()和reset()方法似乎是不安全的。 当我尝试使用buffer.slice()将ChannelBuffer包装在“私有”容器中时,我得到了一个例外,例如“Slice不是可重放的方法......”。 它并不是很复杂,需要扩展一个FrameDecoder并重新实现检查点逻辑...

1 个答案:

答案 0 :(得分:1)

它已成为netty API中的官方Bug,已经修补了。 Tiket here。 我要感谢Netty的社区!