堆概述(一)
堆
在程序運行過程中,堆可以提供動態(tài)分配的內(nèi)存,允許程序申請大小未知的內(nèi)存。堆其實就是程序虛擬地址空間的一塊連續(xù)的線性區(qū)域,它由低地址向高地址方向增長。我們一般稱管理堆的那部分程序為堆管理器。
堆管理器處于用戶程序與內(nèi)核中間,主要做以下工作
1.響應(yīng)用戶的申請內(nèi)存請求,向操作系統(tǒng)申請內(nèi)存,然后將其返回給用戶程序。同時,為了保持內(nèi)存管理的高效性,內(nèi)核一般都會預(yù)先分配很大的一塊連續(xù)的內(nèi)存,然后讓堆管理器通過某種算法管理這塊內(nèi)存。只有當(dāng)出現(xiàn)了堆空間不足的情況,堆管理器才會再次與操作系統(tǒng)進(jìn)行交互。
⒉管理用戶所釋放的內(nèi)存。一般來說,用戶釋放的內(nèi)存并不是直接返還給操作系統(tǒng)的,而是由堆管理器進(jìn)行管理。這些釋放的內(nèi)存可以來響應(yīng)用戶新申請的內(nèi)存的請求。
Linux 中早期的堆分配與回收由Doug Lea實現(xiàn),但它在并行處理多個線程時,會共享進(jìn)程的堆內(nèi)存空間。因此,為了安全性,一個線程使用堆時,會進(jìn)行加鎖。然而,與此同時,加鎖會導(dǎo)致其它線程無法使用堆,降低了內(nèi)存分配和回收的高效性。同時,如果在多線程使用時,沒能正確控制,也可能影響內(nèi)存分配和回收的正確性。Wolfram Gloger在Doug Lea的基礎(chǔ)上進(jìn)行改進(jìn)使其可以支持多線程,這個堆分配器就是ptmalloc。在glibc-2.3.x.之后, glibc中集成了ptmalloc2。
堆相關(guān)的數(shù)據(jù)結(jié)構(gòu)
堆的操作相當(dāng)?shù)膹?fù)雜,那么在glibc內(nèi)部必然也有精心設(shè)計的數(shù)據(jù)結(jié)構(gòu)來管理它。與堆相應(yīng)的數(shù)據(jù)結(jié)構(gòu)主要分為宏觀結(jié)構(gòu),包含堆的宏觀信息,可以通過這些數(shù)據(jù)結(jié)構(gòu)索引堆的基本信息。微觀結(jié)構(gòu),用于具體處理堆的分配與回收中的內(nèi)存塊。
該結(jié)構(gòu)體定義了有6個變量
微觀結(jié)構(gòu) malloc chunk
fd指向下一個元素
bk執(zhí)向前一個元素
一個chunk 在內(nèi)存中的狀態(tài)
這里 上一個chunk加上size 就能找到下一個chunk的位置
當(dāng)該chunk被釋放的時候
當(dāng)一個chunk處于使用狀態(tài)時,它的下一個chunk的prev_size域無效,所以下一個chunk的該部分也可以被當(dāng)前chunk使用。這就是chunk中的空間復(fù)用。
總結(jié)
- 上一篇: outguess秘钥加密--[BJDCT
- 下一篇: CRC32爆破解密脚本工具(三)