一、 内存池的原理和实现
Linux采用的“按需调页”算法,支持三层也是存储管理策略。将每个用户进程4GB长度的虚拟内存划分成固定大小的页面。其中0支3GB是用户空间,3GB到4GB是内核空间,由所有进程共享,但只有内核态进程才能访问。
定义:内存池(MemoryPool)是一种内存分配方式。通常我们习惯直接使用new、malloc等API申请分配内存,这样做的缺点在于:由于所申请内存块的大小不定,当频繁使用时会造成大量的内存碎片并进而降低性能。
内存池:内存池是动态分配内存的设备,只能被特定的内核成分使用。拥有者通常不直接使用内存池,当普通内存分配失败时,内核才调用特定的内存池函数来提取内存池,以得到所需的额外内存。因此内存池只是内核内存的一个储备,用在特定的时刻。这样做的一个显著优点是尽量避免内存碎片看,是的内存分配效率得到提升。
Linux内核的内存管理采取狼藉分配机制,即初始化时将内存池按照内存的大小分成多个级别,8字节的倍数,每个几倍都预先分配20块内存。如果用户申请的内存单位元大于预定义的级别128字节,则直接调用malloc从堆中分配内存。而如果申请的内存小于128字节,则从最相近的内存大小中申请,如果改组的内存存储量小于一定的值,就会根据算法,再次从堆中申请一部分内存加入内存池,保证内存池中有一定量的内存可以使用。
内核内存池初始时从缓冲区申请一定量的内存块,需要使用时从池中顺序查找空闲内存块并返回申请者。回收时也是直接将内存插入池中,如果池已经满了,则直接释放。内存池没有动态增加大小的能力,如果内存池中的内存消耗殆尽,则只能直接从缓存区申请内存,内存池的容量不会随着使用量的增加而增加。
(c++)整个内存池其实就是一个单链表,表头指向第一个没有使用的节点,我们可以吧整个单链表想象成一段链条,调用方法new就是从链条的一端取走一个节点,调用的方法delete就是在链表的一端前面插入一个节点,新插入的节点就是链表的表头。
内存池有点:分析linux2.6内核中的内存池的数据结构及实现,研究表明,使用内存池可以减少内存碎片,提高分配速度,便于内存管理,防止内存泄漏。将内存池的分配方法应用与用户程序,可以提高效率。但是放分配的内存大小增大的时候,使用内存池分配内存的速度有可能会有所降低。
Linux采用的“按需调页”算法,支持三层也是存储管理策略。将每个用户进程4GB长度的虚拟内存划分成固定大小的页面。其中0支3GB是用户空间,3GB到4GB是内核空间,由所有进程共享,但只有内核态进程才能访问。
定义:内存池(MemoryPool)是一种内存分配方式。通常我们习惯直接使用new、malloc等API申请分配内存,这样做的缺点在于:由于所申请内存块的大小不定,当频繁使用时会造成大量的内存碎片并进而降低性能。
内存池:内存池是动态分配内存的设备,只能被特定的内核成分使用。拥有者通常不直接使用内存池,当普通内存分配失败时,内核才调用特定的内存池函数来提取内存池,以得到所需的额外内存。因此内存池只是内核内存的一个储备,用在特定的时刻。这样做的一个显著优点是尽量避免内存碎片看,是的内存分配效率得到提升。
Linux内核的内存管理采取狼藉分配机制,即初始化时将内存池按照内存的大小分成多个级别,8字节的倍数,每个几倍都预先分配20块内存。如果用户申请的内存单位元大于预定义的级别128字节,则直接调用malloc从堆中分配内存。而如果申请的内存小于128字节,则从最相近的内存大小中申请,如果改组的内存存储量小于一定的值,就会根据算法,再次从堆中申请一部分内存加入内存池,保证内存池中有一定量的内存可以使用。
内核内存池初始时从缓冲区申请一定量的内存块,需要使用时从池中顺序查找空闲内存块并返回申请者。回收时也是直接将内存插入池中,如果池已经满了,则直接释放。内存池没有动态增加大小的能力,如果内存池中的内存消耗殆尽,则只能直接从缓存区申请内存,内存池的容量不会随着使用量的增加而增加。
(c++)整个内存池其实就是一个单链表,表头指向第一个没有使用的节点,我们可以吧整个单链表想象成一段链条,调用方法new就是从链条的一端取走一个节点,调用的方法delete就是在链表的一端前面插入一个节点,新插入的节点就是链表的表头。
内存池有点:分析linux2.6内核中的内存池的数据结构及实现,研究表明,使用内存池可以减少内存碎片,提高分配速度,便于内存管理,防止内存泄漏。将内存池的分配方法应用与用户程序,可以提高效率。但是放分配的内存大小增大的时候,使用内存池分配内存的速度有可能会有所降低。