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

Netty出现io.netty.util.internal.OutOfDirectMemoryError的解决咨询

解决Netty的OutOfDirectMemoryError问题

问题原因

你遇到的io.netty.util.internal.OutOfDirectMemoryError是Netty直接内存耗尽导致的:

  • 当前已用直接内存134MB(134217728字节),刚好达到上限阈值
  • 错误发生在SSL解码阶段,说明高并发/长连接场景下,直接内存的分配、回收出现瓶颈,间歇性出现大概率是内存泄漏或者流量峰值超出限制

解决方案

1. 临时提升直接内存上限

这是最快的临时解决办法,直接调整Netty的直接内存阈值:

  • 在JVM启动参数中添加:
    -Dio.netty.maxDirectMemory=268435456
    
    这里设置为256MB,可根据服务器内存情况调整(比如512MB或1GB)。注意Netty的这个参数优先级高于JVM的-XX:MaxDirectMemorySize。

2. 排查并修复内存泄漏

间歇性错误基本是内存泄漏导致的,开启Netty的泄漏检测定位问题:

  • 添加启动参数开启高级泄漏检测:
    -Dio.netty.leakDetection.level=advanced
    
    检测到ByteBuf未正确释放时,会打印完整调用栈,帮你找到未释放内存的代码位置。
  • 新手务必注意:所有手动分配的ByteBuf必须调用release()释放,或者用try-with-resources自动释放(Netty 4.1及以上支持):
    try (ByteBuf buf = ctx.alloc().directBuffer()) {
        // 业务逻辑处理buf
    }
    
  • 检查SSL连接关闭时的资源释放:确保SslHandler在channelInactive事件中正确清理会话缓存和相关内存。

3. 优化ByteBuf分配策略

  • 改用堆内存测试:如果暂时不想处理直接内存问题,可临时改用堆内存分配器(适合低并发场景,高并发下性能会下降):
    // 初始化客户端/服务器时设置
    Bootstrap bootstrap = new Bootstrap();
    bootstrap.group(group)
            .channel(NioSocketChannel.class)
            .option(ChannelOption.ALLOCATOR, UnpooledByteBufAllocator.DEFAULT);
    
  • 调整池化参数:使用默认PooledByteBufAllocator时,可调整池大小和缓存策略,减少内存碎片化:
    PooledByteBufAllocator allocator = new PooledByteBufAllocator(true, 4, 4, 1024, 10);
    bootstrap.option(ChannelOption.ALLOCATOR, allocator);
    

4. 优化SSL配置减少内存消耗

SSL握手和会话管理是内存消耗大户,优化配置可降低内存压力:

  • 开启SSL会话复用,减少重复握手的内存开销:
    SslContext sslContext = SslContextBuilder.forServer(new File("cert.pem"), new File("key.pem"))
            .sessionCacheSize(1000) // 缓存1000个会话
            .sessionTimeout(300)    // 会话超时300秒
            .build();
    
  • 尽量使用长连接,减少频繁创建/销毁SSL连接带来的内存波动。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 22:37:39