• [Java, Netty] PooledUnsafeDirectByteBuf을 Byte[]로 변환하기
    프로그래밍/Java 2023. 12. 19. 14:59
    728x90

    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

    댓글

Copyright ⓒ syudal.tistory.com