使用 Netty 4,当在处理程序中抛出异常时如何处理引用计数对象?
With Netty 4, how do I handle reference counted objects when an exception is thrown inside a handler?
假设我有一个这样的入站通道处理程序:
public class Handler extends ChannelInboundHandlerAdapter {
@Override
protected void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
// msg is actually a reference counted object
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
// Handle exception here, can't release msg since it's not passed.
}
}
由于exceptionCaught
在其签名中没有收到入站消息,似乎无法确保引用计数对象被释放。看来我被迫将 channelRead
的全部内容包装在 try/catch 块中,以确保我可以在不终止整个过程的情况下正确恢复任何异常。这是真的吗?
您应该在 try-finally 中释放引用计数的对象,如 Netty quick start tutorial 所示。
这可以按如下方式完成:
public class Handler extends ChannelInboundHandlerAdapter {
@Override
protected void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
try {
// msg is actually a reference counted object
} finally {
ReferenceCountUtil.release(msg);
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
// Handle exception here, can't release msg since it's not passed.
}
}
请注意我调用了 ReferenceCountUtil.release(msg);
而不是 msg.release()
,这是因为调用第一个会自动检查是否可以释放有问题的对象,而对于后者你需要将对象转换为不同的类型,然后才能调用释放方法。
假设我有一个这样的入站通道处理程序:
public class Handler extends ChannelInboundHandlerAdapter {
@Override
protected void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
// msg is actually a reference counted object
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
// Handle exception here, can't release msg since it's not passed.
}
}
由于exceptionCaught
在其签名中没有收到入站消息,似乎无法确保引用计数对象被释放。看来我被迫将 channelRead
的全部内容包装在 try/catch 块中,以确保我可以在不终止整个过程的情况下正确恢复任何异常。这是真的吗?
您应该在 try-finally 中释放引用计数的对象,如 Netty quick start tutorial 所示。
这可以按如下方式完成:
public class Handler extends ChannelInboundHandlerAdapter {
@Override
protected void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
try {
// msg is actually a reference counted object
} finally {
ReferenceCountUtil.release(msg);
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
// Handle exception here, can't release msg since it's not passed.
}
}
请注意我调用了 ReferenceCountUtil.release(msg);
而不是 msg.release()
,这是因为调用第一个会自动检查是否可以释放有问题的对象,而对于后者你需要将对象转换为不同的类型,然后才能调用释放方法。