0

0

什么是Java中的直接内存管理_ByteBuffer.allocateDirect内存回收逻辑

P粉602998670

P粉602998670

发布时间:2026-02-23 15:42:10

|

825人浏览过

|

来源于php中文网

原创

directbytebuffer 的内存由操作系统管理,jvm 仅通过 cleaner 异步回收,不保证及时性;频繁分配易致 oom,应复用、池化并避免依赖自动清理。

什么是java中的直接内存管理_bytebuffer.allocatedirect内存回收逻辑

DirectByteBuffer 的内存到底归谁管

Java 的 ByteBuffer.allocateDirect 分配的不是堆内存,而是操作系统原生内存(通常通过 mallocmmap),JVM 不直接管理它的生命周期——它靠一个隐藏的 Cleaner 关联到虚引用(PhantomReference)来触发回收。这意味着:**你不能靠 GC 时机预测它何时释放,也不能靠 System.gc() 强制回收**。

  • 分配时 JVM 会记录已用直接内存大小(受 -XX:MaxDirectMemorySize 限制,不设则默认等于 -Xmx
  • 当分配失败抛出 OutOfMemoryError: Direct buffer memory,往往不是因为没空闲内存,而是因为 Cleaner 还没运行、旧缓冲区还没释放
  • 频繁创建/丢弃 DirectByteBuffer 容易堆积未清理对象,尤其在 GC 压力小(如老年代长期不触发 Full GC)时更明显

为什么调用 cleaner.clean() 也不一定立刻释放

即使你手动触发 sun.misc.Cleaner(比如反射拿到并调用),也只是把释放逻辑提交进一个单线程的 Cleaner 队列,实际释放由后台线程执行——这个线程可能被阻塞、调度延迟,甚至在某些 JDK 版本中因线程优先级低而“饿死”。

  • JDK 9+ 中 Cleaner 已迁移到 java.lang.ref.Cleaner,但行为类似:异步、无保证顺序、不保证及时性
  • Unsafe.freeMemory() 是最终释放系统内存的调用,但它只在 Cleaner 线程里执行,无法从应用线程同步等待
  • 别试图用 ByteBuffer.clear()compact() 来“释放”直接内存——它们只重置 position/limit,对底层内存毫无影响

怎么避免 OOM 和内存泄漏

核心思路是:**少分配、复用、早显式清理(如果真有必要)**。不要依赖自动回收扛住高吞吐场景。

关于Objective
关于Objective

本文档主要讲述的是关于Objective-C手动内存管理的规则;在ios开发中Objective-C 增加了一些新的东西,包括属性和垃圾回收。那么,我们在学习Objective-C之前,最好应该先了解,从前是什么样的,为什么Objective-C 要增加这些支持。有需要的朋友可以下载看看

下载
  • 用池化方案:Apache Commons Pool 或 Netty 的 PooledByteBufAllocator,复用 DirectByteBuffer 实例
  • 确认是否真需要 direct:纯内存拷贝、零拷贝网络发送(如 SocketChannel.write(ByteBuffer))才值得;否则堆内 ByteBuffer 更稳
  • 监控关键指标:JVM 启动加 -XX:+PrintGCDetails,观察日志中 Direct buffer memory 行;或用 JMX 查 java.nio:type=BufferPool,name=directMemoryUsed
  • 极端情况可强制触发 Cleaner:调用 System.gc() + 短暂 Thread.sleep(10)(不推荐生产,仅调试),但别写进业务逻辑

JDK 21+ 的变化和现实约束

JDK 21 引入了 ScopedMemoryAccessMemorySegment(属于 Panama 项目),目标是替代 DirectByteBuffer 的手动管理,但目前 ByteBuffer API 仍完全兼容旧逻辑,所有已有代码行为不变。

立即学习Java免费学习笔记(深入)”;

  • 新 API 仍处于 incubating 阶段(--enable-preview),生产环境慎用
  • 即便未来全面迁移,底层仍是 mmap/malloc + Cleaner 模式,只是封装更安全——不会改变“非即时释放”这一根本约束
  • 真正难处理的从来不是“怎么释放”,而是“什么时候该认为它已释放”:操作系统 free 后,内存页未必立刻归还给系统,topps 看到的 RSS 可能滞后数秒甚至更久

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

422

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

595

2023.08.10

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

715

2023.08.10

Java 并发编程高级实践
Java 并发编程高级实践

本专题深入讲解 Java 在高并发开发中的核心技术,涵盖线程模型、Thread 与 Runnable、Lock 与 synchronized、原子类、并发容器、线程池(Executor 框架)、阻塞队列、并发工具类(CountDownLatch、Semaphore)、以及高并发系统设计中的关键策略。通过实战案例帮助学习者全面掌握构建高性能并发应用的工程能力。

94

2025.12.01

CSS position定位有几种方式
CSS position定位有几种方式

有4种,分别是静态定位、相对定位、绝对定位和固定定位。更多关于CSS position定位有几种方式的内容,可以访问下面的文章。

83

2023.11.23

apache是什么意思
apache是什么意思

Apache是Apache HTTP Server的简称,是一个开源的Web服务器软件。是目前全球使用最广泛的Web服务器软件之一,由Apache软件基金会开发和维护,Apache具有稳定、安全和高性能的特点,得益于其成熟的开发和广泛的应用实践,被广泛用于托管网站、搭建Web应用程序、构建Web服务和代理等场景。本专题为大家提供了Apache相关的各种文章、以及下载和课程,希望对各位有所帮助。

418

2023.08.23

apache启动失败
apache启动失败

Apache启动失败可能有多种原因。需要检查日志文件、检查配置文件等等。想了解更多apache启动的相关内容,可以阅读本专题下面的文章。

937

2024.01.16

Java 流式处理与 Apache Kafka 实战
Java 流式处理与 Apache Kafka 实战

本专题专注讲解 Java 在流式数据处理与消息队列系统中的应用,系统讲解 Apache Kafka 的基础概念、生产者与消费者模型、Kafka Streams 与 KSQL 流式处理框架、实时数据分析与监控,结合实际业务场景,帮助开发者构建 高吞吐量、低延迟的实时数据流管道,实现高效的数据流转与处理。

117

2026.02.04

pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

1127

2026.02.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

相关下载

更多

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 3.8万人学习

C# 教程
C# 教程

共94课时 | 10万人学习

Java 教程
Java 教程

共578课时 | 70.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号