從源碼角度剖析VC6下的內存分配與切割的運作

目錄

  • 前言
  • 1、heap初始化
  • 2、第一次分配內存,計算真正區塊大小
  • 3、new_region管理中心
  • 4、__sbh_alloc_new_group()切割第一次分配好的內存
  • 5、開始切割內存

前言

malloc與free帶來的內存管理是應付小區塊的,即SBH(small block heap),這點也可以從源代碼中看出:
VC6下會做門檻檢測

if(size <= __sbh_threshold) {
pvReturn = __sbh_alloc_block(size);
return pvReturn;
}
...
return HeapAlloc(_crtheap,0,size)

VC10下不會做門檻檢測,它總是會調用系統提供的HeapAlloc。這是因為操作系統提供的函數也有類似的功能了。
當然還需要注意,我們分析的步驟是按照函數調用的次序來的:(從下往上的函數調用次序如下)
在這里插入圖片描述

1、heap初始化

首先向操作系統要一大塊內存(如4096),稱為_crtheap.
然后使用HeapAlloc從_crtheap中獲取16個HEADER大小的內存,并獲取內存指針。
每個HEADER長這樣:

圖1
圖2

2、第一次分配內存,計算真正區塊大小

在debug模式下,通過調用malloc_dbg,分配得到32個8字節的內存,即100h.
然后調整大小,擴充一個如下的結構:nDataSize記錄真正大小。gap用戶調試器檢查保護nsize內存。注意gap一共上下兩個,但是結構體里面只定義了上面的那個。

圖1
圖2
我們將這整個內存的大小叫做blockSize: 然后調用heap_alloc_dbg函數,進行結構體與nSize的整合

在這里插入圖片描述
通過調用_heap_alloc_base來獲取每個blockSize內存的頭指針。
然后通過頭尾指針將所有分配出來的block串接起來,變為一個鏈表:

在這里插入圖片描述

頭指針為_pFirstBlock;
尾指針為_pLastBlock;
_heap_alloc_base具體內容
之前在通過heap_alloc_dbg中調用_heap_alloc_base來獲取每個blockSize內存的頭指針。
現在來看看它具體步驟:
1、首先將擴充完的大小與__sbh_threshold進行比較,所過是小區塊就用shb服務,否則由操作系統服務。
小區塊的定義是:這塊內存大小+cookie大小 < 1024個字節

if(size <= __sbh_threshold) {
pvReturn = __sbh_alloc_block(size);
return pvReturn;
}
...
return HeapAlloc(_crtheap,0,size)

接下來看__sbh_alloc_block具體細節:
對擴充完的區塊再次進行擴充,加上8個字節(上下cookie)并且進行roundup操作(變為16的整數倍)
在這里插入圖片描述
以上圖為例,最終得到的結果是0x130,但是在cookie中寫入的卻是131。這是因為由于是16的倍數,所以最后一位一定是0。最后一位0/1表示是在SBH手上還是已經分配出去了。

3、new_region管理中心

之前在第一步heap初始化的時候分配了16個HEADER,每個HEADER現在用來管理1MB的內存。每個HEADER有兩根指針:一根指向虛擬地址空間,一根指向管理中心。
管理中心被稱為new_region。
region設計如下:
它含有:
1個整數
64個char
32個Hi和32個Lo并起來,構成32組,每組64個bit。(用來管理哪些區塊有或者沒有)
32個group,每個group由64根雙向鏈表組成。

圖1
圖2
程序將用這一塊region(大概16KB左右)來控制1MB的虛擬內存空間。 程序通過調用__sbh_alloc_new_region()、__sbh_alloc_new_group()函數開始內存管理。

4、__sbh_alloc_new_group()切割第一次分配好的內存

已知擁有32個group,對應了1MB的虛擬內存空間,平均下來每個group管理32KB內存。
每32KB的內存還要再分割,分成8page(注意這里的內存都是連續的),每page4KB,然后用指針把8個page串起來。串起來之后將它們掛到group的最后一條鏈表。這便是SBH現在所作的事情。
下面紅色部分便是group與32KB內存的具體銜接圖。
在這里插入圖片描述
0xfff…實際上就是-1,作用:
將來回收內存的時候需要合并內存,合并的過程中需要用-1作為阻隔器,即只能合并-1與-1之間的內存。
上-1下面有3格,第一格記錄的是兩個-1之間的內存,一開始大小為4080,后兩格作為指針將page從前到后串聯起來。
每個page大小4096字節,去掉兩個-1,剩下4088個字節。由于每個紅色區塊要保證大小是16倍數。所以需要將4088再分割出去8個字節(也就是保留)。
每個4K都這樣處理,形成如下的圖:
在這里插入圖片描述

5、開始切割內存

先前講到了每個group中有64根雙向鏈表,平均分配下來:
第一條鏈表管理16個字節的內存
第二條鏈表管理32個字節的內存

最后一條管理1024個字節的內存(實際上大于1k的內存全都歸最后一條管理)
在這里插入圖片描述
現在開始想象開始切割page1的內存,當page1內存小于1k的時候就不應該由最后一條鏈表來管,應該要計算,然后將指定鏈表拉過來。現在來看具體的切割:
在之前的步驟中我們以及知道我們需要的內存是多大了:130h(100h+debugHeader+cookie+roundup)
所以,現在還剩下ec0h的內存。切割完后,系統將紅色的地址:007d0ed0,傳出去。
客戶程序拿到該指針,便認為擁有了這一塊內存。
由上可知,切割其實只是cookie的調整 + 指針的傳送。
注意紅色指針還需要調整(扣除debugHeader),調整到右邊的結構塊的綠色部分,該部分才是使用者(ioinit)真正拿到的地址。
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/377336.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/377336.shtml
英文地址,請注明出處:http://en.pswp.cn/news/377336.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

windows常見命令整理(持續更新)

windows常見命令整理 1. 文件1.1. 實時顯示文件 logfile.txt 中新添加的內容&#xff08;類似于linux tail -f&#xff09; 2. 網絡2.1. netstat 3. 進程和任務3.1. tasklist &#xff08;用于列出當前運行的進程及其詳細信息&#xff09;3.2. wmic &#xff08;用于執行各種系…

最長公共子序列求序列模板提_最長公共子序列

最長公共子序列求序列模板提Description: 描述&#xff1a; This question has been featured in interview rounds of Amazon, MakeMyTrip, VMWare etc. 這個問題在亞馬遜&#xff0c;MakeMyTrip&#xff0c;VMWare等訪談輪次中都有介紹。 Problem statement: 問題陳述&…

洛必達法則使用條件

使用條件 1、分子分母同趨向于0或無窮大 。 2、分子分母在限定的區域內是否分別可導。 3、當兩個條件都滿足時&#xff0c;再求導并判斷求導之后的極限是否存在&#xff1a;若存在&#xff0c;直接得到答案&#xff1b;若不存在&#xff0c;則說明此種未定式無法用洛必達法則解…

求根號m(巴比倫算法)

巴比倫算法是針對求根號m的近似值情況的&#xff0c;它的思想是這樣的&#xff1a; 設根號mX0,則如果枚舉有答案X(X<X0)&#xff0c;則m/X>X0,當精度要求不高的時候&#xff0c;我們可以看成Xm/XX0,而如果精度要求比較高&#xff0c;我們只需取X和m/X的平均值作為新的枚舉…

Android面試題

http://blog.csdn.net/aomandeshangxiao/article/category/841452 http://www.cppblog.com/life02/category/18316.html轉載于:https://www.cnblogs.com/DonkeyTomy/articles/2598673.html

r語言 分類變量 虛擬變量_R語言中的變量

r語言 分類變量 虛擬變量R語言| 變數 (R Language | Variables) In the previous tutorial, we have come across the basic information that stands as a pavement for understanding the R language in depth. Now moving future let us educate ourselves about the concep…

算法題復習(快排、鏈表、二分、哈希、雙指針)

目錄1、快速排序復習2、鏈表部分復習203. 移除鏈表元素707. 設計鏈表206. 反轉鏈表142.環形鏈表 II3、二分法復習4、哈希法復習5、雙指針復習**15. 三數之和****18. 四數之和****27. 移除元素****344. 反轉字符串**,簡單&#xff0c;雙指針從兩側往中間靠攏&#xff0c;并隨時s…

Cassandra1.2文檔學習(7)—— 規劃集群部署

數據參考&#xff1a;http://www.datastax.com/documentation/cassandra/1.2/webhelp/index.html#cassandra/architecture/architecturePlanningAbout_c.html 當規劃一個Cassandra集群部署時&#xff0c;關于你初始存儲的數據的數據量你應當有一個好的想法&#xff0c;并且對于…

虛擬機設置NAT

需要開啟虛擬機網絡相關服務&#xff0c; 安裝虛擬網卡&#xff0c; 還有必須安裝 VMware ToolsVMware虛擬機下實現NAT方式上網1. 把你的虛擬網卡VMnet8設置為自動獲得IP、自動獲得DNS服務器&#xff0c;啟用。2. 把你虛擬機中操作系統的“本地連接”也設置為自動獲得IP、自動獲…

窗體震動 C# (不使用Timer控件,控制窗體震動)

private static Point plocation new Point(); public static void StartVibration(Form form)//Form 傳入需要振動的窗體 { plocation form.Location; for (int i 1; i < 41; i)//41&#xff0c;可以理解為震動的時間。…

算法題復習(棧與隊列、二叉樹)

目錄棧與隊列棧用于匹配的問題隊列用于堆二叉樹系列深度遍歷&#xff0c;遞歸與迭代層序遍歷二叉樹屬性二叉樹修改與構造二叉搜索樹公共祖先二叉搜索樹的修改與構造棧與隊列 棧用于匹配的問題 20. 有效的括號 https://leetcode-cn.com/problems/valid-parentheses/ 不匹配的三…

bpsk_BPSK的完整形式是什么?

bpskBPSK&#xff1a;二進制相移鍵控 (BPSK: Binary Phase Shift Keying) BPSK is an abbreviation of "Binary Phase Shift Keying". BPSK是“二進制相移鍵控”的縮寫 。 BPSK is also occasionally called phase reversal keying (PRK), or 2PSK, which is the el…

win7 下安裝oracle 10g

oracle 10g 在win7下安裝&#xff0c;提示程序異常終止&#xff0c;發生未知錯誤 在網上搜結果&#xff1a; 修改Oracle 10G\database\stage\prereq\db\refhost.xml 在 </SYSTEM> <CERTIFIED_SYSTEMS>后面添加 <!--Microsoft Windows 7--> <OPERAT…

poj 1703 Find them, Catch them

題目鏈接&#xff1a;http://poj.org/problem?id1703 題目大意&#xff1a;警察抓獲N個罪犯&#xff0c;這些罪犯只可能屬于兩個團伙中的一個&#xff0c;現在給出M個條件&#xff08;D a b表示a和b不在同一團伙&#xff09;&#xff0c;對于每一個詢問(A a b)確定a&#xff0…

雙向a*搜索算法_雙向搜索算法

雙向a*搜索算法什么是雙音搜索&#xff1f; (What is bitonic search?) Searching a bitonic array is known as bitonic search. An array is said to be bitonic if it has an increasing sequence of integers followed immediately by a decreasing sequence of integers.…

關于LRU緩存簡單記錄以及代碼補全。

目錄大概思路時間空間復雜度分析指針操作具體細節代碼雙向鏈表設計私有成員變量設計:構造函數和析構函數設計&#xff1a;get與put具體設計雙向指針的具體細節添加到頭節點函數刪除尾節點函數刪除節點函數刪除節點函數感想今天面試考到LRU&#xff0c;太緊張了&#xff0c;完全…

碼農干貨系列【4】--圖像識別之矩形區域搜索

簡介 定位某個圖片的矩形區域是非常有用的&#xff0c;這個可以通過手動的選擇某個區域來實現定位&#xff0c;圖片相關的軟件都提供了這個功能&#xff1b;也可以像本篇一個通過程序來實現智能定位。前者會有誤差&#xff0c;效率低下&#xff1b;后者選區精度高&#xff0c;效…

算法題復習(回溯)

目錄base code棋盤問題51. N 皇后37. 解數獨組合問題77. 組合未剪枝優化剪枝優化216. 組合總和 III未剪枝優化剪枝優化17. 電話號碼的字母組合39. 組合總和未剪枝優化剪枝優化40. 組合總和 II,挺重要的&#xff0c;涉及到去重了切割問題131. 分割回文串子集問題78. 子集90. 子集…

pfa是什么意思_PFA的完整形式是什么?

pfa是什么意思PFA&#xff1a;預測性故障分析 (PFA: Predictive Failure Analysis) PFA is an abbreviation of Predictive Failure Analysis. It is a technique of a mechanism of the computer that is used to predict impending failures of software or hardware compone…

SqlServer視圖(view)

--上節回顧--1.什么是事務--2.事務的特征--原子性、一致性、隔離性、持久性--3.與事務相關的t-sql命令--開啟事務&#xff1a;begin transaction--提交事務&#xff1a;commit transaction--回滾事務&#xff1a;rollback transaction ----------------視圖-------------------…