@TOC
图解Kafka内存设计
好久没写技术博客了,今天重新捡起来。本节主要介绍Kafka的内存设计
内存池设计
内存申请
如上图所示,Kafka为了减少Full GC发生的概率,专门设计了BufferPool这个内存池对象,提高内存的使用效率,减少内存回收次数。整个内存池的大小为32M。内存池包含两个了队列,空内存队列和等待内存队列。申请内存的时,如果空内存队列有内存块并且申请内存的大小等于PoolableSize(16K)时,则提取第一个内存块给申请者使用。否者判断可用内存和空内存队列内存两者之和的大小是否满足当前申请内存的大小,若满足则调用ByteBuffer分配申请大小的内存。如果不满足则创建一个Condition对象,加入到等待内存队中,同时分配一点内存给申请者并进入循环,在循环内逐步分配内存给申请者直至达到申请内存大小;或者有线程归还内存并且大小为16K时则从空内存队列中取出第一块给申请者。如果申请超时仍然无法申请到内存,则抛异常同时回收已经分配的内存到池里。
内存归还
有借有还,再借不难。内存也是一样的。
归还时也是要判断当前內存块(ByteBuffer)的大小是否为16K,若是则将当前内存块清空,加入到空内存队列(free)中。否则直接将非池化可用内存(onPooledAvailableMemory)的大小加上待归还的内存块大小。取出内存等待队列中的头一个等待进程,通知它可以来玩了:)
思考
归还时,如果内存块大于16K,是否可以分拆并取整,把数个16K的内存块加入到free队列中,零头加入非池化可用内存。这块可以进一步提高内存利用率,减少full gc的发生。