加入收藏 | 设为首页 | 会员中心 | 我要投稿 源码网 (https://www.900php.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 运营中心 > 建站资源 > 优化 > 正文

看完这篇还不清楚Netty的内存管理,那我就哭了!

发布时间:2019-08-14 19:18:28 所属栏目:优化 来源:零度冰炫
导读:副标题#e# 说明 在学习Netty的时候,ByteBuf随处可见,但是如何高效分配ByteBuf还是很复杂的,Netty的池化内存分配这块还是比较难的,很多人学习过,看过但是还是云里雾里的,本篇文章就是主要来讲解:Netty分配池化的堆外内存的细节,期待可以让你明白!!!
副标题[/!--empirenews.page--]

 说明

在学习Netty的时候,ByteBuf随处可见,但是如何高效分配ByteBuf还是很复杂的,Netty的池化内存分配这块还是比较难的,很多人学习过,看过但是还是云里雾里的,本篇文章就是主要来讲解:Netty分配池化的堆外内存的细节,期待可以让你明白!!!

看完这篇还不清楚Netty的内存管理,那我就哭了!

由于为了更好的表达,文章中的图我最少画了6小时,画的不熟悉,并且也强调一些细节上。

由于该源码中涉及到大量的二进制操作,建议看看其他二进制文章。

ByteBuf重要性

ByteBuf在Netty中一直存在,读写必备!ByteBuf是Netty的数据容器,高效分配ByteBuf至关重要!

看完这篇还不清楚Netty的内存管理,那我就哭了

Netty从socket读取数据。

看完这篇还不清楚Netty的内存管理,那我就哭了

Netty准备把数据写到socket中去。

看完这篇还不清楚Netty的内存管理,那我就哭了

通过这里我们就可以看到,再把数据写socket的之前会判断是否是堆外内存,如果不是会构造一个directbuffer对象的,细节代码如下:

看完这篇还不清楚Netty的内存管理,那我就哭了
看完这篇还不清楚Netty的内存管理,那我就哭了

所以本篇文章就是主要来讲解:Netty分配池化的堆外内存的细节,其实分配堆内存的细节很多也是类似的。

备注: 为什么不是堆外内存还要转堆外内存,为什么加这个判断,我之前也不理解,忽然有天和涤生大佬讨论,讨论讨论就清晰了,后续有空写篇。

总览

看完这篇还不清楚Netty的内存管理,那我就哭了

本次主要讨论的是关于池化内存的分配,PooledByteBufAllocator就是netty分配池化内存的操作入口。

其提供对外常用操作api:

看完这篇还不清楚Netty的内存管理,那我就哭了

Netty在发送数据的时候会判断是否是堆外内存,如果不是会进行封装的:

看完这篇还不清楚Netty的内存管理,那我就哭了

所有这里我们以分配池化的堆外内存为例,进行本文说明。池化的堆内存分配其实流程都差不多的。

下面我们来看看分配示例demo:

看完这篇还不清楚Netty的内存管理,那我就哭了

后续我们都会根据这段简单的demo进行分析。

操作入口类

PooledByteBufAllocator的初始化:

看完这篇还不清楚Netty的内存管理,那我就哭了

进去之后可以看到核心类的一初始化操作:

看完这篇还不清楚Netty的内存管理,那我就哭了

看完这篇还不清楚Netty的内存管理,那我就哭了

看完这篇还不清楚Netty的内存管理,那我就哭了

分配理论是jemalloc,可以理解为java版本的jemalloc实现。

PoolThreadCache

看完这篇还不清楚Netty的内存管理,那我就哭了

通过上图可以清晰的了解到PoolThreadCache的主要数据结构。

开始的时候,这些Cache里面都是没有值的,只有在调用free释放的时候(在后续释放内存中会讲解),才会把之前分配的内存大小放到该cache的queue里面,其实每次分配的时候都是先看看是否缓存里面有,如果有直接返回,没有则进行正常的分配流程(内存分配会讲解)。

我们来看看PoolArena directArena内容:

看完这篇还不清楚Netty的内存管理,那我就哭了

下面我们来看看PoolArena结构。

PoolArena

看完这篇还不清楚Netty的内存管理,那我就哭了

通过下图可以清晰的了解到PoolArena的主要数据结构。

看完这篇还不清楚Netty的内存管理,那我就哭了

在PoolArena里面涉及到PoolChunkList和PoolSubpage对应的结构有PoolChunk和PoolSubpage,我们来详细的看看这2块内容。

PoolChunk

第一次的时候,PoolChunkList、PoolSubpage都是默认值,需要新增一个Chunk,默认一个Chunk是16M。内部会结构是完全二叉树一共有4096个节点,有2048个叶子节点(每个叶子节点大小为一个page,就是8k),非叶子节点的内存大小等于左子树内存大小加上右子树内存大小。

完全二叉树结构如下:

看完这篇还不清楚Netty的内存管理,那我就哭了

这颗完全二叉树在java中是使用数组来进行表示的。

(编辑:源码网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读