java.nio.ByteBuffer-allocateDirect和垃圾收集



我今天读到以下内容:

Direct ByteBuffer对象自动清理其本机缓冲区但是只能作为Java堆GC的一部分来执行,所以它们不能自动响应本地堆上的压力。GC仅发生当Java堆变得非常满时,它无法为堆分配提供服务请求,或者Java应用程序明确请求(而不是推荐,因为它会导致性能问题)。

我的印象是,使用Direct ByteBuffers意味着你必须手动管理本地内存的分配/释放,而且它根本不受GC的约束。然而,本文似乎认为,如果GC确实发生了,则直接ByteBuffer将被收集。

我认为,在进行堆外存储时,主要的动机之一是避免GC可能出现的问题(例如长时间暂停)。

DirectByteBuffer对象是非常小的对象,本质上只是将指针保存到本机内存中。这允许在不扩展托管堆和零拷贝IO的情况下进行分配

所以这些对象通常不会增加GC的压力。

它们消耗的是本机资源、虚拟地址空间,可能还有物理内存或交换空间。如果使用内存映射文件而不是allocateDirect创建的缓冲区,则可能会大大超过可用的物理ram,因为内存将由磁盘存储(类似于交换)支持。

至少通过官方API,你唯一不能做的就是取消直接缓冲区所指向的内存范围的映射。相反,一旦GC收集到缓冲区本身,底层内存就会被释放。

TL;DR:您没有完全手动的内存管理,但您确实摆脱了托管java堆的一些限制。

最新更新