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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > windows >内容正文

windows

Windows内存管理 - 隐藏在new和malloc背后的heap

發(fā)布時(shí)間:2024/4/15 windows 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Windows内存管理 - 隐藏在new和malloc背后的heap 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

??? 先來說,heap是什么,heap就是堆,在不知道具體細(xì)節(jié)的時(shí)候,我們只知道,通過new和malloc,我們可以動(dòng)態(tài)獲得一個(gè)內(nèi)存區(qū)域,用來存放自己的對(duì)象和變量,而這些內(nèi)存區(qū)域都是在heap上的。heap應(yīng)該就是一個(gè)內(nèi)存區(qū)域吧。應(yīng)該會(huì)有很多人這么認(rèn)為過。
??? 后來,學(xué)習(xí)了Windows的內(nèi)存模型和內(nèi)存管理機(jī)制,知道了地址空間,明白了Windows(32bit)給每個(gè)進(jìn)程一個(gè)假象,就好像是進(jìn)程擁有一個(gè)大到4G的內(nèi)存空間。這個(gè)就是虛擬的地址空間,程序在這個(gè)地址空間上訪問數(shù)據(jù),而這個(gè)數(shù)據(jù)的在物理內(nèi)存中的真實(shí)位置是不確定的,可能在物理內(nèi)存的某個(gè)頁中,也可能因?yàn)閾Q頁,存放在頁面文件中。Windows的核心管理著虛擬地址空間和物理內(nèi)存的對(duì)應(yīng)關(guān)系,而作為程序員,我們所見到,只有虛擬地址而已。
??? 操作系統(tǒng)的內(nèi)存管理機(jī)制的絕妙之處在于,一個(gè)進(jìn)程可以使用的地址空間很大,但是除非這些地址被保留后提交,否則就不會(huì)占用真實(shí)的物理內(nèi)存。翻翻MSDN,發(fā)現(xiàn)以下這些API:
?VirtualAlloc
?VirtualAllocEx
?VirtualFree
?VirtualFreeEx
?VirtualLock
?VirtualProtect
?VirtualProtectEx
?VirtualQuery
?VirtualQueryEx
?VirtualUnlock

??
?VirtualAlloc和VirtualAllocEx用來在地址空間上保留和提交一個(gè)區(qū)域。

?VirtualFree和VirtualFreeEx用來釋放或者反提交一個(gè)區(qū)域。

?VirtualLock用于將一個(gè)地址空間上的區(qū)域鎖在物理內(nèi)存上,也就是防止因?yàn)閾Q頁而導(dǎo)致的這個(gè)區(qū)域的數(shù)據(jù)進(jìn)入頁面文件。?VirtualUnlock的作用正相反,是將鎖到物理內(nèi)存上的地址區(qū)域解鎖,使之允許被換頁出物理內(nèi)存。

?VirtualProtect和VirtualProtectEx用于設(shè)置一個(gè)地址區(qū)域的保護(hù)屬性。

?VirtualQuery和VirtualQueryEx用于獲取一個(gè)地址區(qū)域的額外信息。

???
??? 這些函數(shù)是Windows API中,我們能夠接觸到的,內(nèi)存分配的最核心的API了,我們可以對(duì)內(nèi)存分配的過程的許多細(xì)節(jié)做精細(xì)的控制,要考慮的內(nèi)容也很多,比如頁的大小,內(nèi)存分配粒度問題。Windows上所有的內(nèi)存分配都要用到這些函數(shù)。
??? 既然內(nèi)存分配的API都有了,new和malloc有是怎么回事。?
??? 首先,C和C++都是內(nèi)核非常精簡(jiǎn)的語言,關(guān)鍵字很少,很多功能都是通過庫函數(shù)進(jìn)行擴(kuò)充的,而C和C++的運(yùn)行時(shí)庫是這些庫中最不可或缺的一個(gè)庫,它負(fù)責(zé)在C和C++編寫的程序開始執(zhí)行之前,初始化一個(gè)可供程序運(yùn)行的環(huán)境(這個(gè)環(huán)境包括棧、堆、輸入輸出和環(huán)境變量等等),而malloc是運(yùn)行時(shí)庫中負(fù)責(zé)內(nèi)存分配的函數(shù)。
??? C和C++編程語言要做到跨平臺(tái),當(dāng)然就需要有針對(duì)不同平臺(tái)的運(yùn)行時(shí)庫的實(shí)現(xiàn)了。malloc函數(shù),要在Windows上面實(shí)現(xiàn),那最終還是需要用到Windows上面的內(nèi)存分配函數(shù),要在Linux上面實(shí)現(xiàn),那肯定也需要使用Linux的內(nèi)存分配函數(shù)。
??? new和malloc的區(qū)別在于,malloc是運(yùn)行時(shí)庫函數(shù),而new是語言的關(guān)鍵字,關(guān)鍵字是在語言的核心進(jìn)行支持的,目的是支持類的創(chuàng)建和構(gòu)造。new在生產(chǎn)一個(gè)對(duì)象實(shí)例的時(shí)候,必須判斷類的構(gòu)造函數(shù),并準(zhǔn)確的調(diào)用,而光用mallloc分配內(nèi)存是不夠的。這個(gè)是new的特殊之處,但是new的實(shí)現(xiàn)中一定也使用了malloc函數(shù)。
??? 看似malloc可以直接調(diào)用虛擬內(nèi)存分配的API,申請(qǐng)內(nèi)存,可是Windows并沒有這么做,而是在地址空間上又加了一個(gè)層次,這個(gè)就是heap,通過heap來管理一個(gè)區(qū)域的地址空間,這樣就可以有多個(gè)heap,就像把地址空間分成了若干個(gè)小的內(nèi)存池,彼此之間互不影響。
??? 這樣有很多好處,第一,在申請(qǐng)或釋放內(nèi)存的時(shí)候,操作系統(tǒng)要查找未分配或已分配的內(nèi)存區(qū)域的鏈表,這種小型化的內(nèi)存池相比整個(gè)地址空間作為一個(gè)完整內(nèi)存池的方案來說,效率是要高很多的;第二,在多線程運(yùn)行的環(huán)境下,如果線程使用不是同一個(gè)heap,那么也就不需要考慮線程同步的問題了,可以提高多線程的效率。其他的好處,恕我愚鈍,還沒想到。
??? 使用heap的好處,我們平常沒有認(rèn)識(shí)到,因?yàn)槲覀兲?xí)慣于new和malloc了。有些時(shí)候new和malloc不是使用內(nèi)存的好方案,為什么呢?因?yàn)樾省?/p>

??
?? C和C++的運(yùn)行時(shí)庫在初始化的時(shí)候,會(huì)創(chuàng)建一個(gè)heap,叫做運(yùn)行時(shí)庫heap。是的,沒錯(cuò),在這之后就運(yùn)行時(shí)庫不會(huì)再創(chuàng)建其他heap了,也就是說,如果你用malloc申請(qǐng)內(nèi)存,始終是在這個(gè)運(yùn)行時(shí)庫heap上分配內(nèi)存,無論是一個(gè)字節(jié)還是一個(gè)大數(shù)組,這樣一來,這個(gè)heap就會(huì)很零散。
?? 最要命的是,運(yùn)行時(shí)庫heap是一個(gè)序列化的heap,所謂序列化,就是說在這個(gè)heap上面的的所有操作必須有先后順序,比如線程A正在用malloc申請(qǐng)內(nèi)存,這個(gè)時(shí)候線程B馬上也調(diào)用了malloc,但是A的調(diào)用還沒結(jié)束,線程B只能等待。在單CPU單核的機(jī)器上,性能的差異不明顯,在多核多CPU的機(jī)器上,這樣的等待如果多了,就會(huì)明顯的影響多線程的效率了。

?? 繼續(xù)說一些heap的信息。Windows下面,每一個(gè)進(jìn)程都會(huì)創(chuàng)建一個(gè)默認(rèn)的heap,初始大小是1MB,Windows的許多函數(shù)都需要一些臨時(shí)的內(nèi)存塊,這些都是從進(jìn)程的默認(rèn)heap中分配的。如果是一個(gè)C或C++程序,就得加上運(yùn)行時(shí)庫heap,這樣最起碼得有2個(gè)heap,但是我試著創(chuàng)建一個(gè)控制臺(tái)程序,用API統(tǒng)計(jì)一下heap的數(shù)目,竟然有4個(gè)heap,不知道其他的heap是什么時(shí)候創(chuàng)建的。
?? 對(duì)于系統(tǒng)默認(rèn)的heap的訪問必須有線程保護(hù),也就是順序操作(序列化的heap),這個(gè)會(huì)浪費(fèi)一些時(shí)間(上面已經(jīng)說明了)。如果要想使得你的線程以最快的速度訪問heap,你需要為線程創(chuàng)建一個(gè)只被自己訪問的heap,并取消heap的序列化選項(xiàng)。但是默認(rèn)的heap必定是序列化的。


?Windows下面與heap相關(guān)API
?GetProcessHeap
?GetProcessHeaps
?HeapAlloc
?HeapCompact
?HeapCreate
?HeapDestroy
?HeapFree
?HeapLock
?HeapQueryInformation
?HeapReAlloc
?HeapSetInformation
?HeapSize
?HeapUnlock
?HeapValidate
?HeapWalk

?


?這里只羅列一下,怎么使用就參考MSDN吧。

?

http://blog.csdn.net/zencher/archive/2010/05/13/5588748.aspx

總結(jié)

以上是生活随笔為你收集整理的Windows内存管理 - 隐藏在new和malloc背后的heap的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。