Java 理解释放资源
我使用Netty处理HTTP请求/响应。并将以下内容写入管道:Java 理解释放资源,java,netty,Java,Netty,我使用Netty处理HTTP请求/响应。并将以下内容写入管道: public class MyBusinessLogic extends ChannelInboundHandlerAdapter{ public void channelRead(ChannelHandlerContext ctx, Object msg){ ByteBuf bb = ctx.alloc().buffer().writeBytes(//some bytes) ctx.wri
public class MyBusinessLogic
extends ChannelInboundHandlerAdapter{
public void channelRead(ChannelHandlerContext ctx, Object msg){
ByteBuf bb = ctx.alloc().buffer().writeBytes(//some bytes)
ctx.writeAndFlush(bb, ctx.newPromise())
//I did not release bb here
}
}
在日志中,我得到了一些类似于“ByteBuf在发布之前被垃圾收集”
”的警告。。。类似的东西
问题是为什么我们需要自己发布ByteBuf
s?反正都是垃圾收集的。如果我不在这里释放bb
,我会遇到什么样的麻烦
将缓冲区释放添加为通道未来侦听器是否正确
ByteBuf bb = //
ctx.writeAndFlush(response, ctx.newPromise())
.addListener(new ChannelFutureListener(){
public void operationComplete(ChannelFuture f){
buf.release()
}
});
根据:
自Netty版本4以来,某些对象的生命周期由其引用计数管理,因此Netty可以在不再使用对象池(或对象分配器)时将其(或其共享资源)返回到对象池。垃圾收集和引用队列不能提供如此高效的不可访问性实时保证,而引用计数提供了一种替代机制,但带来了一些不便
然而,这并不是完整的解释。Netty ByteBuf还可以访问直接堆内存。这种内存的特殊性在于,当它满了时,它不会运行垃圾收集器,而是抛出一个异常
Netty尝试访问堆内存的原因基本上是因为当处理任何与“通道”一起工作的东西时(例如将文件复制到套接字,或从套接字1复制到套接字2),这会带来很大的速度增量。这比使用数组做同样的事情要好得多,在数组中,较低级别首先需要将其转换为java数组,然后在发送数据包时再次转换
由于堆(直接)内存与垃圾收集器协同工作的方式,这可能意味着在某些情况下,当创建的唯一对象是Netty ByteBufs时,堆内存在垃圾收集器调用之间会变满,因为从垃圾收集器的角度来看,记忆一开始就不完整。由于垃圾收集器中的quark,Netty基本上必须制定一个释放方法,以便在不再需要内存时直接释放内存。相关:。也许这个:值得一读(不是我的网站,只是从一些谷歌结果)@RC。我只是看看答案。我对更多的细节感兴趣。如果
ByteBuf
仍被垃圾收集,那么什么会导致内存泄漏?只有1%的ByteBuf启用了泄漏检测以提高性能,因此默认情况下99%的内存将泄漏:只需挖掘unoledheapbytebuf
的源代码release()
方法最终调用所谓的unmoleedheapbytebuf::freeArray
,它实际上是NO-OP
。顺便问一下,在channelfutureelistener
中完成操作后释放ByteBuf怎么样?这是正确的方法还是有一些缺点?