了解释放资源
Understanding releasing resources
我正在使用 Netty 处理 HTTP request/response。并将以下 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 was garbage collected before it was released
”的警告...类似的东西。
问题是为什么要我们自己发布ByteBuf
?无论如何,它们都是垃圾收集的。这里的bb
不释放会惹上什么麻烦?
只添加缓冲区释放作为通道未来监听器是否正确?
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 尝试访问堆内存的原因基本上是因为在处理任何与 "channels" 一起工作时,这会大大提高速度,例如将内容从文件复制到套接字,或从套接字 1 复制到套接字套接字 2。这比对数组做同样的事情有更好的性能,较低级别首先需要将其转换为 java 数组,然后在发送数据包时再次返回。
由于堆(直接)内存与垃圾收集器一起工作的方式,这可能意味着在某些情况下,当创建的唯一对象是 Netty ByteBufs 时,堆内存在垃圾收集器调用之间变满,因为从垃圾收集器的角度来看,内存从来没有满过。由于垃圾收集器中的这个夸克,Netty基本上不得不做一个释放方法,所以内存不再需要时直接释放。
我正在使用 Netty 处理 HTTP request/response。并将以下 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 was garbage collected before it was released
”的警告...类似的东西。
问题是为什么要我们自己发布ByteBuf
?无论如何,它们都是垃圾收集的。这里的bb
不释放会惹上什么麻烦?
只添加缓冲区释放作为通道未来监听器是否正确?
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 尝试访问堆内存的原因基本上是因为在处理任何与 "channels" 一起工作时,这会大大提高速度,例如将内容从文件复制到套接字,或从套接字 1 复制到套接字套接字 2。这比对数组做同样的事情有更好的性能,较低级别首先需要将其转换为 java 数组,然后在发送数据包时再次返回。
由于堆(直接)内存与垃圾收集器一起工作的方式,这可能意味着在某些情况下,当创建的唯一对象是 Netty ByteBufs 时,堆内存在垃圾收集器调用之间变满,因为从垃圾收集器的角度来看,内存从来没有满过。由于垃圾收集器中的这个夸克,Netty基本上不得不做一个释放方法,所以内存不再需要时直接释放。