關於堆棧(1)

我們總結一下前面講過的:
虛擬內存:
1.虛擬內存可以用於處理大批量數據
內存映射文件:
1.內存映射文件加載exe和DLL可以節省時間和頁文件
2.使用內存映射文件來訪問磁盤上的文件,可以避免I/O讀寫,也不需要爲文件內容進行緩存
3.內存映射文件可以用於進程間的共享
4.對於某些數據量不確定的應用,可以使用稀疏文件

今天主要說的是堆棧:
堆棧的作用是可以用來進行分配較小的數據快,缺點是,分配和釋放內存的速度比其他方法要慢,且無法直接控制物理存儲器的回收

MicroSoft並沒有以文檔的形式來規定堆棧釋放和回收存儲器應該規定的規則,但是,windows98注重內存的使用,因此,只要有可能,他就收回堆棧。windows2000注重速度,因此,即使堆棧不用了,它也不會立即釋放,只有等一段時間不用之後,纔會將內存返回給頁文件

默認堆棧
每個進程都有一個默認堆棧,這個堆棧的大小如果不設置的話就是1MB,若要改變其大小,設定2M,可以使用鏈接開關/HEAP:2097152
默認堆棧相當重要,很多系統函數都需要使用默認堆棧,比如Ansi版本的函數,一般都會把它轉化成Unicode版本,然後再執行,但是執行期間,轉化字符串需要的緩衝區必須要從默認堆棧分配,這一點我們無法更改,且每個函數都是按順序訪問的,不會同時訪問堆棧,這樣就不會破壞堆棧數據

除此之外,我們還可以創建輔助堆棧
爲什麼要創建輔助堆棧
1.保護組件
關於這個,我們先看個圖
這裏寫圖片描述
假設有兩個組件,一個是節點結構的鏈表,一個是branch結構的二進制樹,假設鏈表代碼發生錯誤,使得節點1後面的若干個字節的數據被破壞,這樣就有可能威脅到分支3的數據,這樣,當我們遍歷二進制樹的時候就會發生錯誤
假如這兩個組件分別存放在兩個堆棧中,就不會發生這樣的事情
2.更加有效的管理內存

這裏寫圖片描述
我們假設每個節點結構需要24個字節,每個分支結構需要32個字節,如果節點1和節點3被釋放,這個時候再分配一塊內存給一個新的分支,就會失敗,因爲雖然可用的是48字節,但是都是零碎的,沒有一塊完整的32字節的區域
如果爲每個組件建立單獨的輔助堆棧, 每個堆棧只包含大小相同的對象,那麼釋放一個對象後,另一個對象剛好可以進入被釋放的控件

3.進行本地訪問
內存是按頁分配的,如果兩個組件在兩個頁面上交叉排布,比如節點1在A頁面上,節點2在B頁面上,節點3在C頁面上,CPU訪問3個節點需要訪問3個不同的頁面,如果內存不夠,還會發生內存的置換,這樣就大大降低了程序的運行速度。
如果是節點全部分佈在一個頁面上,分支全部分佈在另一個頁面上,這樣處理節點或者處理分支,就不需要CPU額外引用內存頁面

4.減少線程同步的開銷
按照默認設置,堆棧是順序進行的,即使多個線程試圖同時訪問堆棧,也不會使數據收到損壞,但是這樣的話,就必須執行額外的代碼,以保證堆棧的絕對安全,如果你自己創建一個輔助堆棧,告訴他只有一個線程訪問該堆棧,這樣就不需要執行額外代碼,大大提高了執行效率

5.迅速釋放堆棧
正如上面所說,把所有的節點或者分支建在一個一個堆棧中,如果我不想要了,我只要撤銷這個堆棧,所有的節點或者分支都被釋放了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章