前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深入Netty源码解析内存优化技巧

深入Netty源码解析内存优化技巧

作者头像
JavaEdge
发布2021-02-22 16:10:11
3550
发布2021-02-22 16:10:11
举报
文章被收录于专栏:JavaEdge

1 降低对象大小

能用基本类型就不用包装类

懂得都懂。

应该定义成类变量的不要定义为实例变量

  • 一个类 =》 一个类变量
  • 一个实例 =》一个实例变量
  • 一个类 =》 多个实例
  • 实例越多,浪费越多

当然 netty 会结合这两点!

2 预估分配的内存

  • 对已可预知固定size的HashMap避免扩容 提前计算好初始size或者直接使用 com.google.common.collect.Maps#newHashMapWithExpectedSize
  • 根据接受到的数据动态调整(guess) 下个要分配的Buffer的大小,比如 io.netty.channel.AdaptiveRecvByteBufAllocator

3 零拷贝

逻辑组合代替实际复制

  • CompositeByteBuf

包装替代实际复制

JDK的零拷贝接口

Netty 通过在 DefaultFileRegion 包装了 NIO 的 FileChannel.transferTo() 实现零拷贝:іо.nеttу.сhаnnеl.DеfаultFіlеRеgіоn#trаnѕfеrТо

4 堆外内存

堆外内存生活场景: 烧烤店热季时人满为患,店家就会在门口加摆一些桌子招待新客人。 店内 =》 JVM内部 =》堆(heap) +非堆(non heap) 店外 =》 JVM外部 =》堆外(off heap)

优点

  • 更广阔的“空间”,缓解店铺内压力->破除堆空间限制,减轻GC压力
  • 减少“冗余”细节(烧烤过程是在室外进行的:烤好直接上桌 V.S 烤好还要 进店内) =》避免复制

缺点

  • 需要搬桌子 =》创建速度稍慢
  • 受城管监管、风险大 =》堆外内存受 os 管理

源码

  • 堆外内存/堆内内存的默认选择
  • 切换方式

堆外内存的分配本质

  • 可见依旧调用的 JDK 原生的堆外内存实现。

5 内存池

内存池生活场景: 点菜单的演进 一张纸:一桌客人一张纸 点菜平板:循环使用

为何使用内存池

  • 创建对象开销大 比如堆外内存就是这样
  • 对象高频率创建且可复用
  • 支持并发又能保护系统
  • 维护、共享有限的资源

实现内存池

  • 开源实现:Apache Commons Pool 程序共享,内存竞争较严重
  • Netty轻量级对象池实现io.netty.util.Recycler 基于特定场景才创建

内存池/非内存池的配置切换

根据参数配置判定(切换方式二)

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/12/22 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 降低对象大小
    • 能用基本类型就不用包装类
      • 应该定义成类变量的不要定义为实例变量
      • 2 预估分配的内存
      • 3 零拷贝
        • 逻辑组合代替实际复制
          • 包装替代实际复制
            • JDK的零拷贝接口
            • 4 堆外内存
              • 优点
                • 缺点
                  • 源码
                    • 堆外内存的分配本质
                • 5 内存池
                  • 为何使用内存池
                    • 实现内存池
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档