netty 源码解读三 内存分配相关(1)-buddy 伙伴内存分配算法

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/firebolt100/article/details/80350426

1.前言:

PooledByteBufAllocator 实现相当复杂,其中涉及许多复杂的数据结构类:

1)PoolArena

2)PoolChunk 

3)PoolSubpage

5)PoolThreadCache

还有其他相关辅助类包括 PoolChunkList

其核心思想是利用了为 FreeBSD 设计的 jemalloc 内存分配算法和 buddy  分配算法。为了更好地解读 netty 内存分配,本节首先着重介绍 buddy  分配算法。

2.算法

内存管理,特别是内存分配一直是操作系统一个基本问题。固定的划分模式会限制活跃进程的数量,而且如果进程请求的大小与可用的分割大小匹配效果不佳,会导致内存空间的使用效率很低。动态划分模式使得维护更复杂,包括内存合并的开销。而伙伴算法就是权衡折中的一种算法。最早由贝尔电话实验室的 Ken C Knowlton 在1965年的《A fast storage allocator》一文中提出。

在伙伴算法中,把用来分配的内存作为一整块2次幂大小的空间。当请求到达时,如果请求的大小大于初始大小空间的一半,那么整块内存都会被分配。否则,这个内存块会一分为二(这两块内存块互为伙伴,算法名即来源于此),这时候再一次判断请求的大小是否大于其中一块子内存块的一半,如果大于,则这块子块将被分配。如果小于,那么再将其中一个子块一分为二,以此类推,直到请求的大小大于分割后的子块的一半,若未找到,则直到分割系统允许的最小单位为止,然后再将相应内存块分配。

在此算法中,当一个进程结束时,分配给进程的内存块会被释放。只要有可能,一个未分配的内存块就会试图与其伙伴块合并以便形成一个更大的空闲内存块。如果两个内存块是由同一个父内存块一分为二产生的,那么他们就互为伙伴。

下面的例子展示了伙伴算法的具体分配过程。假设初始内存块大小为1024KB,表左侧为进程每次请求的内存大小。

分配时优先考虑从低地址开始适配内存块。

展开阅读全文

内存分配相关的问题

02-11

声明:我所使用的C语言集成开发环境是turboc2.0。rn 我想用C语言写出一个程序,借助于该程序,我可以计算出(或得出)此程序运行时,操作系统为其运行所分配的内存空间的范围,和此内存区首字节的地址。我如何做到这一点呢?我没有太多的思路在,请朋友们帮忙。rn 我首先谈一下我的看法与认识,在这些看法与认识中有一些肯定是不适宜,或者说是错误的,请阅读者持一种审慎的态度。rn 1.对于某可执行程序而言,其运行所需的内存空间是由操作系统负责分配的。rn 2.我所使用的操作系统的版本是microsoft windows xp[version 5.1.2600]。请问此操作系统自带的DOS操作系统的版本是什么?有没有什么命令或方法可以确定出此操作系统自带的DOS操作系统的版本是什么?rn 3.DOS操作系统是不是一个单任务操作系统,在我的印象中,DOS操作系统是一个单任务操作系统。rn 4.DOS操作系统是一个单任务操作系统。那么只有当某可执行文件中的所有指令都执行完毕后,才有可能去执行另外一个可执行文件中的指令,这种认识对吗?rn 5.在DOS操作系统下,某可执行文件的两次运行,DOS都会为其分配同一块内存区,是吗?rn 6.在DOS操作系统中,肯定有一个模块负责将某可执行文件的目标代码装入某块内存区,这个模块在我的印象中的名字为装载器(loader).在我的印象中,好像没有什么书籍是来讲述装载器的。如何来设计一个装载器呢.rn 好了,先到此为止吧。请朋友们就您所了解的发表您的看法。多谢了。 论坛

没有更多推荐了,返回首页