我理解当分配一个directbytebuffer时,它不受垃圾收集的影响,但我想知道的是包装对象是否被垃圾收集.
例如,如果我分配了一个新的DirectByteBuffer dbb,然后使用dbb.duplicate()复制(浅层复制)它,我会在同一块内存中有两个包装器.
这些包装纸是否需要进行垃圾收集?如果我做了
while(true){
DirectByteBuffer dbb2 = dbb.duplicate();
}
Run Code Online (Sandbox Code Playgroud)
我最终会自己OOM吗?
我一直在尝试编写一个HTTP客户端来同时获取多个提要(最多1k),这也是学习Netty 4的练习.
我的问题是,如果有一个很好的解释,新的ByteBuf基础设施如何工作?谁"拥有"他们,他们是如何分享的(是吗?)?ChannelPipeline中的每个ChannelHandler都有它自己的ByteBuf吗?
这是一个令我困惑的例子:
我将以下类的实例添加到HTTP客户端管道:
public class MyFilter extends MessageToMessageDecoder<HttpObject> {
@Override
protected Object decode(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
// do some work, but leave msg unchanged
BufUtil.retain(msg); // Why do I need to call BufUtil.retain(msg) ???
return msg;
}
Run Code Online (Sandbox Code Playgroud)
如果我没有在msg上调用BufUtil.retain,它似乎得到了GCd,我得到了各种各样的虚假错误.
我已经阅读了各种StackOverFlow QA以及有关Netty内存泄漏的外部链接和博客,从ReferenceCountedObjects和ManuallyHandlingReferenceCounting,BufferOwnership,TwitterBlog,ChannelOutboundHandlerFlushedBufferLeak以及源自这些页面的其他链接开始.
我理解如果应用程序在完成资源后不释放资源,实际内存本身将被GC,但Netty的池大小仍会增加并导致内存泄漏.
上面链接解释这一点的引用引用"即使缓冲区本身是垃圾收集,用于存储池的内部数据结构也不会.","PooledByteBufAllocator也使用Recycler来"汇集"ByteBuf容器(不是它指的是自己的记忆.)"
有人可以解释一下如何发生这种情况吗?如果ByteBuf是一个引用内存的容器,那么在ByteBuf仍然在Netty内存池中时如何收集内存?我想象Netty维护了一个ByteBuf(s)池,并在它的引用计数变为0时重用它所引用的内存.通过这个假设,我无法理解如果内存本身ByteBuf仍然存在于Netty的池中,它是如何被GC 的?
有人可以用简单的语言澄清一下吗?