簡體   English   中英

在Netty 4中直接使用內存

[英]Direct memory usage in Netty 4

我有一個關於Netty直接內存管理的問題。

我創建了一個直接緩沖區:

@GetMapping("/new/buffer/netty/unpool")
@Synchronized
public void newBufferNetty() {
    UnpooledByteBufAllocator allocator  = UnpooledByteBufAllocator.DEFAULT;
    ByteBuf buffer = allocator.buffer(100 * 1024 * 1024);
    _myByteBufList.add(buffer);
    log.info("buffer[{}] created", buffer);
}

然后我觀察了top生成的信息,我發現內存沒有變化(RES,SWAP和free)。 我很困惑,因為它是正常的(操作系統內存信息將改變),如果我以NIO方式,如ByteBuffer.allocateDirect(1024*1024*100);

在我調查了源代碼之后,我發現NIO通過new DirectByteBuffer(cap)創建了一個directByteBuffer,而Netty實際上是通過new DirectByteBuffer(addr, cap) 后一種方式,Netty沒有調用Bits.reserve(size, cap) ,這就是為什么我認為為什么沒有top顯示的變化。

我還發現Netty使用自己的計數器DIRECT_MEMORY_COUNTER來跟蹤它分配的直接內存。

我的問題是:

  1. 為什么Netty在分配直接內存時不會調用Bits.reserve

  2. 為什么Netty必須使用自己的計數器來監控直接內存的使用?

  3. (這是讓我最困惑的一個)當我創建一個Netty緩沖區時,為什么os內存沒有變化(UnpooledUnsafeNoCleanerDirectByteBuf)

非常感謝你提前。

我只回答3分。 前兩點只能由Netty作者解釋。

如前所述,Netty使用new DirectByteBuffer(addr, cap)來創建直接緩沖區。 並且傳遞的內存地址是由Unsafe.allocateMemory返回的,它調用系統內存分配工具。 https://en.wikipedia.org/wiki/C_dynamic_memory_allocation中所述

在懶惰的內存分配方案中,例如Linux操作系統中經常出現的內存分配方案,大型堆不一定保留等效的系統內存; 它只會在第一次寫入時執行此操作(非映射內存頁的讀取返回零)。 其粒度取決於頁面大小。

因此,預計top不會反映Netty直接緩沖區分配。

相比之下, ByteBuffer.allocateDirect使用Unsafe.setMemory與分配后設置為零的所有字節Unsafe.allocateMemory 此類行為在Javadoc https://docs.oracle.com/javase/7/docs/api/java/nio/ByteBuffer.html#allocateDirect(int)中指定

新緩沖區的位置將為零,其限制將是其容量,其標記將是未定義的,並且其每個元素將初始化為零。

它解釋了為什么ByteBuffer.allocateDirect分配由top反映。 請注意,僅在首次使用分配的內存后才會增加應用程序內存使用量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM