看完这篇还不清楚Netty的内存管理,那我就哭了!
depthMap的值初始化后不再改变,memoryMap的值则跟着节点分派而改变。 ![]() 这个值太多就不都截图了,就是把上面那颗完全二叉树用数组暗示了罢了,只是值存的不是节点的下标而是存的树的深度罢了。 depthMap数组值为0暗示可以分派16M空间,假如为1 暗示可以分派8M,,假如为2暗示嗯可以分派4M,假如为3暗示可以分派2M ……………………假如为11暗示可以分派8k空间。 假如该节点已经分派完成,就配置为12即可。 怎么确定必要分派的巨细在深度是几多? 假如必要分派的内存规格化之后,是小于8k,那么在8k上面分派即可(即深度为11)。 假如为8k可能大于8k那么通过下面代码就可以定位到深度了:
知道深度之后,怎么举办定位到谁人节点呢??? ![]() 找到该节点之后,先把该节点表现占用,在更新起父节点父节点的父………………如下: ![]() SubpagePool ![]() 上面的图就是关于SubpagePool的内存布局了。我们在分派page的时辰,按照memoryMap对付的值就知道是否被分派了,那么假如是subpagePool呢? subpagePool分为2类:tinySubpagePools和smallSubpagePools,巨细对付也对付上面的图内里了,每类都是牢靠巨细的,假如分派256b的巨细,那么一个page就是8k,8*1024/256 = 32块。那么怎么怎么暗示每个还被分派了呢?
因为一个long占用的字节数为64,我们这里仅仅是必要暗示32个,以是行使一个long即可了,二进制每位 1暗示已经行使了,0暗示还未行使。 ![]() 因为subpage不只仅必要定位到完全二叉树在谁人节点,还必要知道在long的第几个 而且是第几位,以是要伟大一些: ![]() 通过一个long的前32位来暗示subpage的第几个long的第几位上面,通事后32来暗示在完全二叉树的谁人节点上面,美满。 分派焦点 分派进口:ByteBuf byteBuf = alloc.directBuffer(256); 举办跟进代码: ![]() 我们来看:PooledByteBuf buf = newByteBuf(maxCapacity); 构建PooledByteBuf工具。最后返回PooledByteBuf工具。 我们来看下类担任布局: ![]() 全部ByteBuf byteBuf = alloc.directBuffer(256);这句话是没有什么题目的,不会报错。 我们来看看newByteBuf(maxCapacity)的细节实现: ![]() 这里借助了Netty增进实现的Recycler工具池技能。Recycler计划也很是优良,后续可以专门写篇Recycler文章,本日不是重点,我们只要知道因为分派PolledByteBuf工具的价钱有点大,假如必要频仍行使到PolledByteBuf工具,而且对机能有所要求,那么池化技能是一个不错的选择(好比我们早年行使的线程池、数据库毗连池等都是相同原理),池化技能在必然水平上面镌汰了频仍建设工具带来的机能开销。其拭魅这个相同的头脑非经常见(好比我们查询数据库本钱高,缓存到redis,思绪也是一样的),在本篇后续中还可以领会到(PoolThreadCache)。 通过PooledByteBuf buf = newByteBuf(maxCapacity);仅仅是获取到了一个初始工具罢了。 分派的焦点在:allocate(cache, buf, reqCapacity); ![]()
(编辑:湖南网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |