概述
netty内存管理中涉及到的几个历史概念:
buddy memory allocation
wiki上介绍的很详尽,算法也比较易懂。首先选定可分配的最小内存block作为order-0,然后按照2的整数倍逐级递增,一直到某个block为可分配内存的上限位置。举个例子,比如我们设定order-0的block大小为1k,那么order-1的大小就是2^11k=2k,order-2就是2^21k=4k,以此类推order-10就是2^10*1k=1M了。每次应用在申请内存的时候,总是尝试在寻找满足条件的最小内存block,如果没有空闲的,那么就把大的block进行split创建出符合要求的block。而当应用释放内存时,会尝试把邻接的空闲内存(buddy memory)进行合并,这样就能避免有大内存需求的时候无法分配了。
从直观上来看,这种分配方式减少了内存碎片,通过block的方式来整块整块的分配可用内存,牺牲了一定的内存利用效率,却能够很大程度上避免因为大量内存碎片而造成无法有效分配给应用使用。类似的联想到了HDFS对其存储的数据同样是按照固定大小的block来管理,虽然浪费了一定的磁盘空间,却能够有效的对整个文件系统进行管理。考虑到算法的形式,一般都是用二叉树的形式来管理各个内存block,而一旦知道某个block的内存地址和大小,就能够很方便的计算出它的 buddy memory block 的内存段。
slab allocation
buddy memory allocation虽然在内存分配和回收上比较高效,但是也有一个比较明显的弊端,那就是比block临界值高一点点的内存申请只能落到一个更大的block上去,造成的结果就是block内的内存被大量浪费。例如order-2的block大小时64k,当试图申请一个66k的可用内存时,只能给它分配order-3的内存块大小为128k,那么这里看到的内存利用率就很差了。slab allocation 尝试通过重用已分配的内存空间来解决这个问题,有点类似对象池化的概念。
IBM有一篇介绍的文章