You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何DirectByteBuffer的分配与回收成本更高?

DirectByteBuffer 分配与回收成本更高的原因解析

先纠正一个核心误解

你之前的认知有误:DirectByteBuffer 的实际内存并不是在 JVM GC 堆里,它的真实内存块是分配在操作系统的本地内存(Native Memory)中,JVM 堆里只存了一个很小的 DirectByteBuffer 对象,用来做引用句柄。这是理解成本差异的关键。

分配时的额外开销

调用 allocateDirect(int capacity) 时,底层要做这些事:

  • 调用操作系统的内存分配函数(比如 Linux 用 malloc,Windows 用 VirtualAlloc),从本地内存划一块连续区域。这个过程需要和操作系统内核交互,属于内核态系统调用,开销比 JVM 堆内的快速分配(比如 TLAB 分配)大得多。
  • JVM 在堆里创建一个 DirectByteBuffer 对象,记录本地内存的地址、容量等元数据,同时绑定一个 Cleaner 对象(负责后续的内存回收)。
  • 有些场景下,JVM 还得给这块本地内存做初始化(比如清零),这也会多耗 CPU。

回收时的额外开销

DirectByteBuffer 的回收流程比堆内 Buffer 复杂很多:

  • 当堆里的 DirectByteBuffer 对象被 GC 标记成垃圾后,不会直接释放本地内存,得等 ReferenceHandler 线程处理对应的虚引用(Cleaner 是基于虚引用实现的)。
  • ReferenceHandler 线程触发 Cleaner 的清理动作,调用操作系统的内存释放函数(比如 free 或 VirtualFree),把本地内存还给操作系统。这个跨线程的异步处理,比堆内内存被 GC 直接回收的同步流程延迟更高、开销更大。
  • 如果本地内存占太多,JVM 可能会触发 Full GC 来强制清理没用的 DirectByteBuffer,而 Full GC 本身的开销就远大于 Young GC。

和堆内 ByteBuffer 的对比

堆内 ByteBuffer(比如 HeapByteBuffer)的内存直接来自 JVM 堆,分配时直接从 TLAB 或 Eden 区拿,回收时由 GC 直接处理,全程在 JVM 内部搞定,不用频繁和操作系统内核交互,所以分配回收成本更低。

内容的提问来源于stack exchange,提问作者light

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 09:21:04