2017-12-10 31 views
1

나는 HTTP 요청/응답을 처리하기 위해 Netty를 사용하고있다. 그리고 파이프 라인 아래로 다음 ByteBuf 작성 : 로그에서해제 리소스 이해하기

public class MyBusinessLogic 
extends ChannelInboundHandlerAdapter{ 
    public void channelRead(ChannelHandlerContext ctx, Object msg){ 
     ByteBuf bb = ctx.alloc().buffer().writeBytes(//some bytes) 
     ctx.writeAndFlush(bb, ctx.newPromise()) 
     //I did not release bb here 
    } 
} 

을 내가 가지고 경고 일부 유사에 "ByteBuf was garbage collected before it was released"... 그 비슷한.

질문은 우리 스스로 ByteBuf을 공개해야하는 이유는 무엇입니까? 그들은 어쨌든 가비지 수집됩니다. bb을 여기에 공개하지 않으면 어떤 문제가 발생할 수 있습니까?

향후 채널 수신자로 출시되는 버퍼를 추가하는 것이 맞습니까?

ByteBuf bb = // 
ctx.writeAndFlush(response, ctx.newPromise()) 
.addListener(new ChannelFutureListener(){ 
    public void operationComplete(ChannelFuture f){ 
     buf.release() 
    } 
}); 
+0

관련 항목 : https://stackoverflow.com/questions/46326821/severe-leak-bytebuf-release-was-not-called-before-its-garbage-collected-ne https://stackoverflow.com/questions/ 29805270/leak-bytebuf-release-was-before-the-garbage-collected-spring. 어쩌면이 : https://logz.io/blog/netty-bytebuf-memory-leak/ (일부 Google 결과에서 내 사이트가 아님) 읽기 가치가 있습니다. –

+0

@RC. 나는 그 대답을 보았다. 나는 조금 더 세부적으로 흥미 롭습니다. 'ByteBuf'가 가비지 수집되는 경우 메모리 누수가 발생할 수 있습니까? –

+0

모든 ByteBufs의 1 %만이 성능을 위해 누출 감지가 켜져 있으므로 기본적으로 메모리의 99 %가 누출됩니다. http://netty.io/wiki/reference-counted-objects.html#leak-detection-levels – Ferrybig

답변

3

http://netty.io/wiki/reference-counted-objects.html에있어서의 Netty 객체에 (또는 공유 자원)을 반환 할 수 있도록

의 Netty 버전 4부터, 특정 개체의 수명주기는, 그 참조 카운트에 의해 관리된다 풀 (또는 객체 할당 자)을 더 이상 사용하지 않는 즉시. 가비지 수집 및 참조 대기열은 도달 불가능 성을 실시간으로 효율적으로 보장하지 못하며 참조 계산은 약간의 불편 함을 희생하면서 대체 메커니즘을 제공합니다.

그러나 이것은 완전한 설명이 아닙니다. Netty ByteBuf는 또한 직접 HEAP 메모리에 액세스 할 수 있습니다. 이 메모리는 가비지 컬렉터가 가득 차면 실행되지 않고 대신 예외가 발생하는 특수한 메모리입니다.

Netty가 힙 메모리에 액세스하려고하는 이유는 기본적으로 파일에서 소켓으로 또는 소켓 1에서 소켓 2로 "파일"을 복사하는 것과 같이 "채널"과 함께 작업 할 때 큰 속도 증가분을 제공하기 때문입니다. 이것은 배열을 가지고 동일한 일을하는 것보다 훨씬 더 나은 성능을 가지고 있는데, 낮은 레벨은 먼저 그것을 자바 배열로 변환하고 패킷을 보낼 때 다시 되돌려 야합니다.

힙 (직접) 메모리가 가비지 수집기와 함께 작동하기 때문에 만든 유일한 개체가 Netty ByteBufs 인 특정 경우에 가비지 수집기 호출간에 힙 메모리가 가득차는 것을 의미 할 수 있습니다. 가비지 컬렉터의 관점에서 보았을 때 메모리는 처음부터 채워지지 않았습니다. 가비지 수집기에있는이 쿼크 때문에 Netty는 기본적으로 해제 메소드를 만들어야하므로 더 이상 필요하지 않을 때 메모리가 직접 해제되었습니다.

+0

'UnpooledHeapByteBuf'의 소스를 파헤 쳤습니다. 'release()'메서드는 실제로'NO-OP' 인 소위'UnpooledHeapByteBuf :: freeArray'를 호출합니다. –

+0

Btw, 'ChannelFutureListener'에서 작업이 완료되면 ByteBuf를 해제하는 방법은 무엇입니까? 올바른 방법입니까 아니면 몇 가지 단점이 있습니까? –