netty不抛出directmemoryexhaustedexception,实际抛出outofmemoryerror: direct buffer memory;原因在于jvm底层通过bits.reservememory校验失败时固定抛此错误,且该错误为error而非exception,不可被catch(exception)捕获。

Java 中没有内置的 DirectMemoryExhaustedException 类。
Netty 本身也不抛出名为 DirectMemoryExhaustedException 的异常。这是个常见误解——开发者常期望 JVM 或 Netty 在堆外内存(Direct Memory)耗尽时自动抛出一个明确的、专属的异常,但实际情况更底层、更隐蔽。
真正发生的是:当尝试分配 Direct Memory 超过 -XX:MaxDirectMemorySize 限制时,JVM 会先尝试触发 Full GC(试图回收已弃用的 ByteBuffer),若仍无法腾出足够空间,则直接抛出 OutOfMemoryError: Direct buffer memory。
Netty 的 PooledByteBufAllocator 在池化分配失败时,也会最终落到这个 OOM 错误上,不会封装或转换成自定义异常类型。
为什么不会抛出 DirectMemoryExhaustedException?
Java 规范和 HotSpot 实现中,不存在该异常类。所有 Direct Memory 分配都通过 java.nio.Bits.reserveMemory(long, int) 进行校验,失败时固定抛出:
OutOfMemoryError("Direct buffer memory")- 该错误继承自
Error,不是Exception,不可被常规catch(Exception)捕获 - Netty 所有分配路径(如
allocator.directBuffer())最终都依赖 JDK 的ByteBuffer.allocateDirect(),逃不开这个机制
如何检测和响应 Direct Memory 耗尽?
不能靠捕获虚构异常,而要主动监控与防御:
-
启动时显式设置上限:务必配置
-XX:MaxDirectMemorySize=512m(否则默认≈堆最大值,易掩盖问题) -
运行时监控:通过
ManagementFactory.getMemoryMXBean().getMemoryUsage()查看direct内存使用量(注意:JDK 7+ 支持) -
Netty 自带指标:启用
PooledByteBufAllocatorMetric,获取usedDirectMemory()、numDirectArenas()等数据 -
OOM 日志兜底:加
-XX:+HeapDumpOnOutOfMemoryError -XX:ErrorFile=...,配合-XX:+PrintGCDetails定位 Direct Memory 泄漏源头
常见误判场景
你以为是 Direct Memory 耗尽,实际可能是:
-
未正确释放 ByteBuf:
ReferenceCounted.release()忘记调用,导致池化内存无法复用(表现为 usedDirectMemory 持续增长) -
使用了 Unpooled(非池化)缓冲区:每次分配都走 JDK 原生
allocateDirect,绕过 Netty 池,更快触达 JVM 限制 -
Native 层泄漏(如 JNI、SSL 引擎):Netty 的
SslHandler在某些 OpenSSL 版本下可能持有未释放的 native memory,不计入directusage 统计,但同样耗尽系统资源
如果真想“抛出”自定义异常怎么办?
可以封装分配逻辑,主动检查后干预:
// 示例:包装 allocator.directBuffer()
long used = PooledByteBufAllocator.DEFAULT.metric().usedDirectMemory();
long max = PlatformDependent.maxDirectMemory();
if (used + expectedSize > max * 0.95) {
throw new IllegalStateException("Near DirectMemory exhaustion: " + used + "/" + max);
}
return allocator.directBuffer(size);
但这只是预警,**无法替代 JVM 的真实分配失败处理**;真正超限时,仍会落到 OutOfMemoryError。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











