java - 了解释放资源

标签 java netty

我正在使用 Netty 处理 HTTP 请求/响应。并将以下 ByteBuf 写入管道:

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?无论如何,它们都是垃圾收集的。不在这里发布bb会惹上什么麻烦?

将缓冲区释放添加为 channel future 监听器是否正确?

ByteBuf bb = //
ctx.writeAndFlush(response, ctx.newPromise())
.addListener(new ChannelFutureListener(){
   public void operationComplete(ChannelFuture f){
       buf.release()
   }
});

最佳答案

根据 http://netty.io/wiki/reference-counted-objects.html :

Since Netty version 4, the life cycle of certain objects are managed by their reference counts, so that Netty can return them (or their shared resources) to an object pool (or an object allocator) as soon as it is not used anymore. Garbage collection and reference queues do not provide such efficient real-time guarantee of unreachability while reference-counting provides an alternative mechanism at the cost of slight inconvenience.

但这并不是完整的解释。 Netty ByteBuf 也可以直接访问 HEAP 内存。此内存的特殊之处在于它在满时不会运行垃圾收集器,而是抛出异常。

Netty 尝试访问堆内存的原因基本上是因为这在处理任何与“ channel ”一起工作时会带来很大的速度增量,例如将内容从文件复制到套接字,或从套接字 1 复制到套接字 2。这比对数组做同样的事情性能要好得多,在数组中,较低级别首先需要将其转换为 java 数组,然后在发送数据包时再次返回。

由于堆(直接)内存与垃圾收集器一起工作的方式,这可能意味着在某些情况下,当创建的唯一对象是 Netty ByteBufs 时,堆内存在垃圾收集器调用之间变满,因为从垃圾收集器的角度来看,内存从一开始就没有满。由于垃圾收集器中的这个夸克,Netty 基本上不得不制定一个释放方法,以便在不再需要时直接释放内存。

关于java - 了解释放资源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47741283/

相关文章:

java - 如何在 JList 上添加滚动条? [JAVA]

java - 如何监听 fragment 上 Activity 中按钮的点击操作?

java - Netty Decoder 在 Windows 和 Linux 中生成不同的输出

java - 检测迟到的响应

java - Spring Integration 并行处理,无需聚合

java - 将字符串转换为 float ?

java - Android - GsonRequest 返回 null

java - Netty 中用于服务器端计划任务/事件的最佳方法

spring-boot - Docker - java netty_tcnative 的问题

java - Netty 4 - 管道头部的出站消息被丢弃