我已经从ReferenceCountedObjects和ManuallyHandlingReferenceCounting,BufferOwnership,TwitterBlog,{{3}开始,阅读了各种StackOverFlow QA以及有关Netty内存泄漏的外部链接和博客},以及源自这些页面的其他链接。
据我所知,如果应用程序在完成资源后不释放资源,实际内存本身将被GC,但Netty的池大小仍会增加并导致内存泄漏。
上面链接中的一些引用解释了这一点是“即使缓冲区本身是垃圾收集的,用于存储池的内部数据结构也不会。”,“PooledByteBufAllocator也使用Recycler来”汇集“ByteBuf容器(不是它自己引用的内存)。“
有人可以解释一下如何发生这种情况吗?如果ByteBuf
是一个引用内存的容器,那么在ByteBuf
仍然在Netty内存池中时如何收集内存?我想象Netty维护了一个ByteBuf
(s)池,当它的引用计数变为0时重用它所引用的内存。有了这个假设,我无法理解如果{{{{{{{{{ 1}}仍然存在于Netty的池中?
有人可以用简单的语言澄清一下吗?
答案 0 :(得分:2)
所以让我试着在这里澄清一下......基本上Netty本身使用“不同”的池来存储本身和它周围的容器。
容器是ByteBuf。所以这里需要做的是将它集中在一个Reycler(它基本上是一个对象池)中。这里要注意的重要一点是,它将对用于实际存储字节的实际底层内存(也称为存储)的引用“置零”。
字节本身(将通过ByteBuf容器公开)抵制在不同的池中。此池本身仅包含ByteBuf的后备存储,但不包含ByteBuf本身。后备存储可以是堆上(byte [])或堆外(本机/直接内存)。
因此,这些都可能是理论上内存泄漏的原因。实际上,大多数内存泄漏都是由于没有调用ByteBuf.release()而导致内存泄漏。