亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

.NET?Core內(nèi)存結構體系(Windows環(huán)境)底層原理解析

 更新時間:2025年02月12日 08:48:40   作者:叫我安不理  
文章介紹了物理內(nèi)存和虛擬內(nèi)存的區(qū)別,以及Windows系統(tǒng)中虛擬內(nèi)存的管理方式,物理內(nèi)存是計算機硬件中的實際RAM,而虛擬內(nèi)存是由操作系統(tǒng)管理的抽象內(nèi)存層,感興趣的朋友一起看看吧

物理內(nèi)存與虛擬內(nèi)存物理內(nèi)存

  • 物理內(nèi)存(Physical Memory)
    定義:物理內(nèi)存是計算機硬件中的實際RAM(如DDR5內(nèi)存條),直接通過總線與CPU連接,用于臨時存儲運行中的程序和數(shù)據(jù)。
  • 虛擬內(nèi)存(Virtual Memory)
    定義:由操作系統(tǒng)管理的抽象內(nèi)存層,通過結合物理內(nèi)存和磁盤空間(如頁面文件或交換分區(qū)),為程序提供連續(xù)且獨立的內(nèi)存空間。

用戶只需要與虛擬內(nèi)存地址打交道,而無需關心數(shù)據(jù)到底分配在哪里

眼見為實

物理頁4K對齊

在Windows系統(tǒng)下,以4K為最小粒度,這個單位叫做物理頁,并以4K的整數(shù)倍分配內(nèi)存。比如申請1k分配4k,申請5k分配8k

眼見為實

void page4k() {
	for (int i = 0; i < 200; i++) {
		//1k 的占用
		LPVOID ptr = VirtualAlloc(NULL, 1024 * 1, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
		printf("i=%d, 1k, address:%#0.8x \n", i + 1, ptr);
	}
	for (int i = 200; i < 400; i++) {
		//5k 的占用
		LPVOID ptr = VirtualAlloc(NULL, 1024 * 5, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
		printf("i=%d, 5k, address:%#0.8x \n", i + 1, ptr);
	}
	getchar();
}

申請1k分配4k

申請5k分配8k

物理內(nèi)存與虛擬內(nèi)存如何映射?

Windows系統(tǒng)采用二叉樹結構(5層)來實現(xiàn)高效映射。

舉個例子,某個32bit的內(nèi)存地址為:0x77b01a42,其二進制為:01110,11110,11000,00001,101001000010

  • 前20位用來構建頁表樹,實現(xiàn)物理頁的的高效映射
  • 后12位映射物理頁的偏移量

操作系統(tǒng)以4K為一個單位對內(nèi)存進行分組,4G內(nèi)存=102410241024*4/(4/1024)=1048576物理頁,如此龐大的物理頁,,采用5層二叉樹來提高索引效率

眼見為實:以notepad為例

任務管理:

Windbg:

可以看到非常明顯的不同,任務管理器顯示占用44.6mb內(nèi)存,而windbg顯示占用489.531mb內(nèi)存,這是為什么呢?答:顯示邏輯不同,任務管理器顯示的是Private WorkingSet,指的是物理內(nèi)存的地址,即內(nèi)存條上的內(nèi)存,而Windbg是顯示映射到的物理頁,Commit指的是虛擬內(nèi)存地址,這包括內(nèi)存條上的內(nèi)存,pagefile,image三種

眼見為實:可視化觀察 虛擬地址=>物理地址

使用windbg進入內(nèi)核態(tài),這很重要,大家可以猜猜原因。

隨便找一個字符串的內(nèi)存地址

  • 使用dp觀察虛擬地址
  • 使用!vtop 觀察映射信息
  • 使用!db觀察物理地址

眼見為實:空指針區(qū)與用戶態(tài)區(qū)

windows/linux在默認情況下,會開啟ASLR,需要關閉此技術才能復現(xiàn)。ASLR 是一種針對緩沖區(qū)溢出攻擊等內(nèi)存攻擊技術而設計的安全特性。在沒有 ASLR 的情況下,程序加載到內(nèi)存中的位置通常是固定的,攻擊者可以預測程序中各種模塊(如可執(zhí)行文件、動態(tài)鏈接庫等)的加載地址,進而利用這些固定地址來構造惡意代碼進行攻擊,比如在緩沖區(qū)溢出攻擊中精準定位跳轉地址來執(zhí)行惡意指令。而啟用 ASLR 后,操作系統(tǒng)在每次啟動程序時會隨機化程序的內(nèi)存布局,包括可執(zhí)行文件、動態(tài)鏈接庫、堆、棧等的加載地址,使得攻擊者難以準確預測內(nèi)存地址,大大增加了攻擊的難度。

Reserved與Commit

  • Reserved
    在虛擬地址上申請一段內(nèi)存空間,此時操作系統(tǒng)也會同步創(chuàng)建頁表樹,但此時并未映射到物理內(nèi)存,此時對該虛擬內(nèi)存的讀寫會拋異常
  • Commit
    頁表樹調(diào)配真實的物理內(nèi)存,此時才能正常寫入

眼見為實:Reserved

void  mem_reserved() {
	LPVOID ptr = VirtualAlloc(NULL, 4 * 1024, MEM_RESERVE, PAGE_READWRITE);
	*(int*)(ptr) = 10;  //在首地址上寫入內(nèi)容。
	printf("num=%d", *(int*)ptr);
}

眼見為實:Commit

void  mem_commit() {
	LPVOID ptr = VirtualAlloc(NULL, 4 * 1024, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
	*(int*)(ptr) = 10;  //在首地址上寫入內(nèi)容。
	printf("num=%d", *(int*)ptr);
}

NT堆

NT堆是 Windows NT 內(nèi)核引入的內(nèi)存管理組件,主要負責進程內(nèi)的堆內(nèi)存分配與釋放。在 Windows 系統(tǒng)里,進程可以使用 NT 堆來動態(tài)分配和管理內(nèi)存,比如程序中使用 malloc()(C 語言)、new(C++) 等函數(shù)進行內(nèi)存分配時,底層通常就依賴 NT 堆機制。

上面說到,VirtualAlloc方法它會一次性分配 64k 整數(shù)倍的內(nèi)存段,內(nèi)部對象按4k的內(nèi)存頁對齊.如果讓application直接操作VirtualAlloc,難免會造成大量的內(nèi)存浪費。為了提高內(nèi)存性能與使用效率,Windows又提供了一層抽象,以提供更細顆粒度的內(nèi)存管理。它的名字叫做NT堆

  • 在32bit平臺上:8byte為一個分配粒度
  • 在64bit平臺上:16btye為一個分配粒度

  • CRT堆:C運行時使用的堆,默認是對NT堆的簡單封裝
  • 托管堆:用作特殊用途的,自行實現(xiàn)的一套內(nèi)存池管理機制。比如GC堆

從圖中可以看出,使用NT與否取決于程序員本身。完全可以繞過NT堆,直接使用VirtualAlloc來分配內(nèi)存,只要你接收內(nèi)存浪費。

眼見為實:GC堆,底層使用VirtualAlloc分配內(nèi)存

static void Main(string[] args)
        {
            var rand = new Random();
            List<string> list = new List<string>();
            for (int i = 0; i < 100000; i++)
            {
                var str = string.Join(",", Enumerable.Range(0, rand.Next(1, 1000)));
                list.Add(str);
                Console.WriteLine($"i={i},length={str.Length}");
            }
            Console.ReadLine();
        }

在bp KERNELBASE!VirtualAlloc 下斷點

眼見為實:CRT堆/NT堆,底層使用VirtualAlloc分配內(nèi)存

?
#include <iostream>
#include <Windows.h>
void crt_c() {
	for (int i = 0; i < 10000000; i++) {
		int* ptr = (int*)malloc(sizeof(int) * 1000);
		*(ptr) = 10;
		printf("第 %d 次分配 \n", i);
	}
}
?

在 bp ntdll!NtAllocateVirtualMemory 下斷點

到此這篇關于.NET Core內(nèi)存結構體系(Windows環(huán)境)底層原理淺談的文章就介紹到這了,更多相關.NET Core內(nèi)存結構體系內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論