-
[Java, Netty] PooledUnsafeDirectByteBuf을 Byte[]로 변환하기프로그래밍/Java 2023. 12. 19. 14:59728x90
PooledUnsafeDirectByteBuf
PooledUnsafeDirectByteBuf는 Netty에서 제공하는 풀링(pooling) 및 unsafe 메모리 액세스를 통해 성능을 향상시키려는 목적으로 디자인된 바이트 버퍼(ByteBuf) 중 하나이다.
EchoServer 예제
Netty의 EchoServer 예제를 살펴보면 EchoServerHandler.java에 아래와 같은 부분이 있다.
@Sharable public class EchoServerHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { ctx.write(msg); } ... }
Netty ~ 4.0
이때, object msg는 PooledUnsafeDirectByteBuf를 자료형으로 갖는데 4.0 버전까지는 아래와 같은 방식으로 버퍼에 직접 접근이 가능했다.
Bytebuf buf = ByteBuf.readBytes(2); byte[] b = buf.array();
Netty 4.1 ~
하지만, 4.1 버전부터 UnsupportedOperationException: direct buffer 오류를 출력하며 직접 접근을 막는다. 이는 기본 버퍼 타입이 heap에서 direct로 변경되었기 때문인데 heap 버퍼의 경우 소켓에 버퍼를 쓰게 될 때 direct 버퍼로 한 번 복사한 뒤에 써야 하기 때문에 성능상 불이익이 있기 때문이다.
따라서 아래와 같은 방식으로 버퍼의 내용을 배열을 할당한 뒤 복사하여 사용해야 한다.
@Override public void channelRead(ChannelHandlerContext ctx, Object msg) { ByteBuf buf = (ByteBuf) msg; byte[] array; int offset; int length; if (buf.hasArray()) { array = buf.array(); offset = buf.arrayOffset() + buf.readerIndex(); length = buf.readableBytes(); } else { array = new byte[buf.readableBytes()]; offset = 0; length = array.length; buf.getBytes(buf.readerIndex(), array); } //System.out.println(byteArrayToHexaString(array)); ctx.write(msg); }
참고
https://groups.google.com/g/netty-ko/c/YpqNXLVAtQU?pli=1
728x90댓글