카테고리:

2 분 소요

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);
    }

ctx.write(msg);
}

참고

https://groups.google.com/g/netty-ko/c/YpqNXLVAtQU?pli=1

태그: byte[], ByteBuf, Direct, Direct buffer, Heap, java, netty, PooledUnsafeDirectByteBuf, UnsupportedOperationException

업데이트: