首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Netty 4中的直接内存使用

Netty 4中的直接内存使用
EN

Stack Overflow用户
提问于 2016-12-02 08:23:33
回答 1查看 4K关注 0票数 6

我对Netty的直接内存管理有个问题。

我通过以下方式创建一个直接缓冲区:

代码语言:javascript
复制
@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、交换和空闲)。我很困惑,因为如果我像ByteBuffer.allocateDirect(1024*1024*100);那样以NIO的方式做这件事的话(操作系统内存信息会改变),那就很好了。

在研究了源代码之后,我发现NIO通过new DirectByteBuffer(cap)创建了一个new DirectByteBuffer(cap),而Netty实际上是通过new DirectByteBuffer(addr, cap)创建的。以后一种方式,Netty没有调用Bits.reserve(size, cap),这就是我认为top没有显示任何更改的原因。

我还发现Netty使用自己的计数器DIRECT_MEMORY_COUNTER来跟踪它分配的直接内存。

我的问题是:

  1. 为什么Netty在分配直接内存时不调用Bits.reserve
  2. 为什么Netty必须使用自己的计数器来监视直接内存的使用?
  3. (这是我最困惑的地方)当我创建一个Netty缓冲区(UnpooledUnsafeNoCleanerDirectByteBuf)时,为什么os内存没有变化?

先谢谢你。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-03-22 10:28:38

我只回答3分。前2点只能由Netty作者解释。

如前所述,Netty使用new DirectByteBuffer(addr, cap)创建直接缓冲区。所传递的内存地址是由Unsafe.allocateMemory返回的,它调用系统内存分配设施。正如在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反映的。注意,应用程序内存使用率只有在第一次使用分配的内存后才会增加。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40927651

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档