日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

侯捷 - C++ Startup 揭密:C++ 程序的生前和死后 (二)

發布時間:2023/12/9 c/c++ 53 豆豆
生活随笔 收集整理的這篇文章主要介紹了 侯捷 - C++ Startup 揭密:C++ 程序的生前和死后 (二) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2.內存分配
先膨脹大小決定要多大內存,然后去拿內存,拿完后函數返回,然后設置區塊串接。

2.1 計算分配的大小并設定值


malloc_crt:

調試模式——使用一般的malloc分配內存
非調試模式——malloc_dbg分配內存并登記一些信息(所在的FILE,LINE)。
因此,任何一個C++程序第一次分配的內存大小都是 IOINFO_ARRAY_ELTS * sizeof(ioinfo) = 256 。它用來作為_cdecl_ioinit()函數,即IO初始化。

在調試模式下,要加上上下文等相關信息,加完的長度要登記在cookie之中(圖中的00000131,在之前的130的基礎上需要1個bit登記狀態),最后要進行字節對齊。

100h(轉化位10進制:256)+ 24h(36) + 8h(8) ?= 12ch -> 130h (16的邊界)。上圖字節補齊的4個字節沒有畫出。

我們來看heap_alloc_dbg函數:

heap的客戶(需要被分配內存的地方)可能是CRT本身 ,可能應用程序。在要完內存后,若小于1K,該區塊將被膨脹(上文提出),膨脹完后會去SBH挖取一塊內存(后文將介紹),然后區塊將被串接起來(如下圖Debug Heap 雙向鏈表)。

heap_alloc_bae:內存門檻檢查,小于1K將從SBH拿取內存,大于將從操作系統的內存池去拿(下圖不小心備注錯了)

2.2 去SBH拿取內存


在32位的電腦沒有64位變量可以用,bitvGroup被分為了Hi和Lo兩部分,BITVEC是unsigned int型,為32位。所以,共有[32]組,每組64bits。

作為heap的管理者,怎么去管heap的區塊呢?我們都是挖一大塊內存,有需要的時候切出去,當我回收的時候它們的大小是相同的:比如我給ABC3個人,它們需要不同大小的內存,它們還給我的時候,如果還的大小是一樣的,我就想辦法把它管理在一起,而不要散落在原始的物理的那一部分,例如我們可以使用特殊的設計將它串在一起(如上圖,將內存串接起來)。

回到上圖,該設計準備了64條雙向鏈表,負責管理64種大小。當回收的時候,有相同的大小,我們就把他鏈在特定的某個鏈表上(邏輯上是連續的,物理上卻不是)。

1 MegaByte,拿出其中的1/32即32K(因為其不希望一次管理太多內存),在將32K切為8塊,每塊為4K。

將page放大來看:

當切出130bytes出去立馬就變成了131bytes了,我們之前說過,因為它的這個設計需要1個bytes表示它的狀態是給出去了還是在SBH手中。?

0xffffffff表示為-1(上下個占8個byte),用來防止鏈表合并。4096-8*2=4088。前面講過希望設計大小是16的倍數,最靠近16邊界的是4080,因此8bytes保留。

?總結:

首先,我們有16個header,每一個header管理的事情是1M里面的32K切成8塊,這8塊是由64條鏈表來管理。

一開始是最后一條鏈表負責把page8鏈接起來(130=304/16=19,從0開始排列,19-1=18。理論應該是#18 List進行供應,但因為現在這些鏈表都是空的,只有最后一個鏈表是有掛載page,所以第18號鏈表是空的,最后發現最后一個鏈表的page起著作用,所以在page中把130bytes切出去了)

在page中把130bytes切割出來。130bytest、是所有程序都會面臨,_ioinit()需要的內存大小就是130bytes,于是剩下ec0bytes 。這就是首次內存分配。

接下來對page1繼續切割(只有當page1 內存切割完成后,才會去切割page2的內存),當切割至第15次,開始釋放。

鏈表的各自任務是以16在變化的,所以由#35 鏈表進行回收。#35 鏈表的指針將指向240bytes的地址。

這樣回收由什么好處呢?下一次客戶需要240bytes大小空間時,#35 鏈表將直接給它。

當第16次分配內存時,將分配b0大小。操作系統將從之前釋放的240bytes中的空間重新切割。240-b0=190,剩下的190將重新分配給#24 List維護管理。所以,內存切割分配是個動態的過程,不斷調整所屬的鏈表。

區塊的合并

合并后的空間也將重新分配給鏈表進行管理。

內存塊將回到最初始的狀態,理論上它可以在合并,但是應為我們前面說過,特意放上separate分隔的東西(0xffffffff),所以它不能繼續合并。

?
————————————————
版權聲明:本文為CSDN博主「Jeff_」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/weixin_40539125/article/details/101083127

總結

以上是生活随笔為你收集整理的侯捷 - C++ Startup 揭密:C++ 程序的生前和死后 (二)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。