Netty内存管理--内存分配器PooledByteBufAllocator

系列文章目录

1. Netty网络应用基础
2. Java I/O
3. IO/模型
4. 网络应用编解码
5. Netty Pipeline
6. Netty EventLoopGroup&EventLoop
7. Netty ThreadLocal&FastThreadLocal
8. Netty Future&Promise
9. Netty内存管理–(旧)PoolChunk&伙伴分配
10. Netty内存管理–内存池空间规格化SizeClasses
11. Netty内存管理–PoolChunk&PoolSubPage
12. Netty内存管理–内存池PoolArena
13. Netty内存管理–内存分配器PooledByteBufAllocator
14. Netty ObjectPool

一、写在前面

到这里想必你已了解了Netty内存规格化, PoolChunk、PoolSubPage、PoolArena3个关键的类。本篇想聊聊直接使用的内存分配器PooledByteBufAllocator。虽然背后还是由前面3个关键类做支持, 但是PooledByteBufAllocator基于实际场景做了一些额外的优化。本文重点关注在优化和支持优化的相关调整。

二、实际场景

问题对策
虽然PoolArena可以管理PoolChunk和PoolSubPage, 但并发场景下, 共享对象如何解决线程间竞争问题?创建线程数量相等的PoolArena, 每个线程绑定自己的PoolArena尽可能消除竞争
业务场景中的小对象(比如IM系统中的一条文字消息大多小于8K)其数量非常多, 频繁分配和回收浪费CPU?回收阶段延迟回收, 尽可能重用已分配内存而不是申请新内存

1. 尽可能消除竞争

  1. 鉴于Netty本身是网络通信库, 其内存管理面向网络IO场景。内存分配器最终被EventLoop结合, 实现高效的IO。默认的EventLoop数量是CPU核心数*2, 因此默认的分配器会创建对等数量的PoolArena。
  2. 前面已经聊过Netty中支持ThreadLocal优化相关的FastThreadLocal和FastThreadLocalThread在线程绑定这里也会发挥作用。
  3. 至于哪个PoolArena应该和哪个Thread绑定, 这是个负载均衡问题。Netty在PoolArena中增加了线程数字段, PooledByteBufAllocator会从所有的PoolArena中选择一个绑定线程数最小的给当前线程使用。
  4. 由于实际向OS申请空间是由线程申请触发, 因此最终创建的对象更多了, 但不会立刻占用太多内存。

2. 延迟回收(分配复用)

  1. PoolThreadCache作为PoolThreadLocalCache的实际内容, 其中支持对已分配的Normal和Small分配做缓存, 并在超过最大数量时释放部分缓存内容。
  2. 由于存在cache, 因此在后续的分配和回收中都需要增加cache维护相关逻辑, 相关的PoolChunk,PoolSubPage和PoolArena的代码中都可以看到PoolThreadCache参数;

三、逻辑调整

分配逻辑调整

  1. 分配空间前先尝试获得线程绑定的PoolThreadCache;
  2. 获得PoolThreadCache关联的PoolArena, 委托PoolArena完成实际的分配(PoolArean更下层的委托此处不再过多讨论);
  3. 将最终得到的PooledByteBuf关联到PoolThreadCache;

回收逻辑调整

  1. 回收空间时, 第一步缓存到关联的PoolThreadCache中, 具体对象为MemoryRegionCache;
  2. 如果由于超过最大容量缓存失败则释放掉对象本身, 空间则委托给PoolArena来释放(PoolArean更下层的委托此处不再过多讨论);

四、小结

以上就是PooledByteBufAllocator解决并发环境下的共享和性能问题过程, 基本思路是消除竞争和空间复用, 可以作为工程中类似问题的一个参考。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值