如何安全地释放 netty 缓冲区?
How to release netty buffer safely?
我正在使用 Netty 4.0,我已经阅读了描述正常行为的 Reference counted objects guide,但是当发生异常时我不知道如何释放 ByteBuf
。
例如:
protected void encode(ChannelHandlerContext ctx, Object msg, List<Object> out) throws Exception {
ByteBuf buf = null;
if (msg instanceof HttpMessage) {
if (state != ST_INIT) {
throw new IllegalStateException("unexpected message type: " + StringUtil.simpleClassName(msg));
}
@SuppressWarnings({ "unchecked", "CastConflictsWithInstanceof" })
H m = (H) msg;
buf = ctx.alloc().buffer();
// Encode the message.
encodeInitialLine(buf, m);//
encodeHeaders(m.headers(), buf);
buf.writeBytes(CRLF);
state = HttpHeaders.isTransferEncodingChunked(m) ? ST_CONTENT_CHUNK : ST_CONTENT_NON_CHUNK;
}
// Bypass the encoder in case of an empty buffer, so that the following idiom works:
//
// ch.write(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
//
// See https://github.com/netty/netty/issues/2983 for more information.
if (msg instanceof ByteBuf && !((ByteBuf) msg).isReadable()) {
out.add(EMPTY_BUFFER);
return;
}
if (msg instanceof HttpContent || msg instanceof ByteBuf || msg instanceof FileRegion) {
if (state == ST_INIT) {
throw new IllegalStateException("unexpected message type: " + StringUtil.simpleClassName(msg));
}
final long contentLength = contentLength(msg);
if (state == ST_CONTENT_NON_CHUNK) {
if (contentLength > 0) {
if (buf != null && buf.writableBytes() >= contentLength && msg instanceof HttpContent) {
// merge into other buffer for performance reasons
buf.writeBytes(((HttpContent) msg).content());
out.add(buf);
} else {
if (buf != null) {
out.add(buf);
}
out.add(encodeAndRetain(msg));
}
} else {
if (buf != null) {
out.add(buf);
} else {
// Need to produce some output otherwise an
// IllegalStateException will be thrown
out.add(EMPTY_BUFFER);
}
}
if (msg instanceof LastHttpContent) {
state = ST_INIT;
}
} else if (state == ST_CONTENT_CHUNK) {
if (buf != null) {
out.add(buf);
}
encodeChunkedContent(ctx, msg, contentLength, out);
} else {
throw new Error();
}
} else {
if (buf != null) {
out.add(buf);
}
}
}
当encodeInitialLine(buf, m);
抛出异常时,如何释放buf
?
您应该将整个方法包装在一个 try-finally 块中,并且在 finally 块中,您应该检查 buf 是否为 null。如果它不为空,请调用 buf.release()
.
protected void encode(ChannelHandlerContext ctx, Object msg, List<Object> out) throws Exception {
ByteBuf buf = null;
try {
...
} finally {
if (buf != null) {
buf.release();
}
}
}
我正在使用 Netty 4.0,我已经阅读了描述正常行为的 Reference counted objects guide,但是当发生异常时我不知道如何释放 ByteBuf
。
例如:
protected void encode(ChannelHandlerContext ctx, Object msg, List<Object> out) throws Exception {
ByteBuf buf = null;
if (msg instanceof HttpMessage) {
if (state != ST_INIT) {
throw new IllegalStateException("unexpected message type: " + StringUtil.simpleClassName(msg));
}
@SuppressWarnings({ "unchecked", "CastConflictsWithInstanceof" })
H m = (H) msg;
buf = ctx.alloc().buffer();
// Encode the message.
encodeInitialLine(buf, m);//
encodeHeaders(m.headers(), buf);
buf.writeBytes(CRLF);
state = HttpHeaders.isTransferEncodingChunked(m) ? ST_CONTENT_CHUNK : ST_CONTENT_NON_CHUNK;
}
// Bypass the encoder in case of an empty buffer, so that the following idiom works:
//
// ch.write(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
//
// See https://github.com/netty/netty/issues/2983 for more information.
if (msg instanceof ByteBuf && !((ByteBuf) msg).isReadable()) {
out.add(EMPTY_BUFFER);
return;
}
if (msg instanceof HttpContent || msg instanceof ByteBuf || msg instanceof FileRegion) {
if (state == ST_INIT) {
throw new IllegalStateException("unexpected message type: " + StringUtil.simpleClassName(msg));
}
final long contentLength = contentLength(msg);
if (state == ST_CONTENT_NON_CHUNK) {
if (contentLength > 0) {
if (buf != null && buf.writableBytes() >= contentLength && msg instanceof HttpContent) {
// merge into other buffer for performance reasons
buf.writeBytes(((HttpContent) msg).content());
out.add(buf);
} else {
if (buf != null) {
out.add(buf);
}
out.add(encodeAndRetain(msg));
}
} else {
if (buf != null) {
out.add(buf);
} else {
// Need to produce some output otherwise an
// IllegalStateException will be thrown
out.add(EMPTY_BUFFER);
}
}
if (msg instanceof LastHttpContent) {
state = ST_INIT;
}
} else if (state == ST_CONTENT_CHUNK) {
if (buf != null) {
out.add(buf);
}
encodeChunkedContent(ctx, msg, contentLength, out);
} else {
throw new Error();
}
} else {
if (buf != null) {
out.add(buf);
}
}
}
当encodeInitialLine(buf, m);
抛出异常时,如何释放buf
?
您应该将整个方法包装在一个 try-finally 块中,并且在 finally 块中,您应该检查 buf 是否为 null。如果它不为空,请调用 buf.release()
.
protected void encode(ChannelHandlerContext ctx, Object msg, List<Object> out) throws Exception {
ByteBuf buf = null;
try {
...
} finally {
if (buf != null) {
buf.release();
}
}
}