netty 最大非堆内存大小限制
读码心得
近期碰到 netty 报 io.netty.util.internal.OutOfDirectMemoryError 错误,排查发现是 netty 最大非堆内存大小限制导致的。
netty 4.1.70.Final 版本,io.netty.util.internal.PlatformDependent 类中,MAX_DIRECT_MEMORY 常量定义如下:
通过 maxDirectMemory0() 方法,获取系统最大非堆内存大小,单位为字节。
其通过多种方式获取最大非堆内存大小,优先级如下:
- 通过反射执行
VM.maxDirectMemory()方法获取 - 通过
MXBean解析JVM参数(-XX:MaxDirectMemorySize)获取
- 通过反射执行
若上述读出的值都是
0,则使用Runtime.getRuntime().maxMemory()读取当前最大可使用内存作为最大非堆内存大小
代码见: PlatformDependent#maxDirectMemory0
真正使用时,使用另一个参数,DIRECT_MEMORY_LIMIT,作为最大非堆内存大小,单位为字节,其获取代码如下:
long maxDirectMemory = SystemPropertyUtil.getLong("io.netty.maxDirectMemory", -1); |
所以,若未设置 -XX:MaxDirectMemorySize 参数,且设置了最大堆大小较小,那么 netty 最大非堆内存大小就会受限于最大堆大小。这容易导致 netty 报 io.netty.util.internal.OutOfDirectMemoryError 错误。