• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            以前寫過一篇理解程序內(nèi)存, 當(dāng)時(shí)主要是針對用戶態(tài),下面再稍微深入一點(diǎn):


            我們以32位程序?yàn)槔ú粏⒂肁WE), 總共4G虛擬空間,其中低2G屬于用戶態(tài), 高2G屬于操作系統(tǒng)內(nèi)核, 每個(gè)程序都有自己的低2G用戶空間, 高2G內(nèi)核空間是所有程序共享的。高2G內(nèi)核空間中, 屬于同一Session的程序又共享相同的session空間:


            x86系統(tǒng)所有的內(nèi)存以64K邊界粒度, 4K頁面大小分配。


            用戶態(tài)的內(nèi)存空間,按用途分可以分為: image, mapped file, heap, stack, free等
            按狀態(tài)分可以分為:Free, reserved, commit;
            Commit的內(nèi)存,在被訪問時(shí)又可能以不同的狀態(tài)存在, 可能是已經(jīng)提交到物理內(nèi)存(RAM),也可能是已頁文件的形式存在后臺, 如果是頁文件形式,訪問時(shí)會觸發(fā)換頁操作。


            我們平時(shí)以任務(wù)管理器或者Process Explorer, 經(jīng)常會看到一些不同內(nèi)存術(shù)語:
            virtual size: reserve和commit的虛擬內(nèi)存
            Private bytes: 已經(jīng)commit的私有虛擬內(nèi)存
            working set: commit的虛擬內(nèi)存中已經(jīng)被加載到物理內(nèi)存中的部分
            WS private / 內(nèi)存(專用工作集): 不能和其他程序共享的working set


            這些內(nèi)存的大小關(guān)系怎么樣?
            virtual size 肯定是最大的; WS private肯定是最小的;working set和private bytes大小不好定, 因?yàn)閣orking set雖然是表示物理內(nèi)存, 但它包含共享和非共享兩部分, 而private bytes雖然是虛擬內(nèi)存,卻只包含私有部分。
            另外我們平時(shí)看程序的內(nèi)存泄漏,主要可以看private bytes 和 WS private.


            我們程序里使用的虛擬地址, 它在訪問時(shí)是如何別轉(zhuǎn)成真正的物理地址的?

            1. 我們的虛擬地址被分為頁目錄索引,頁表索引,字節(jié)偏移三部分
            2. 根據(jù)CR3寄存器得到當(dāng)前進(jìn)程的頁目錄表地址, 根據(jù)頁目錄索引得到頁目錄表項(xiàng)目(PDE), 然后就可以得到該頁表的地址
            3. 根據(jù)頁表索引,得到頁表項(xiàng)目(PTE)的地址, 然后即可定位到該頁面, 根據(jù)偏移字節(jié)即可訪問真正的物理內(nèi)存


            操作系統(tǒng)采用按需換頁的算法來實(shí)現(xiàn)內(nèi)存的訪問, 也就是說系統(tǒng)會在真正訪問一個(gè)地址的時(shí)候才會把該地址轉(zhuǎn)成有效的物理地址, 如果訪問失敗, 會觸發(fā)換頁異常, 再真正加載該頁面換到物理內(nèi)存。系統(tǒng)用虛擬地址描述符(VAD, virtual address descriptor)組成的平衡二叉樹來跟蹤所有的虛擬內(nèi)存,以確定所有虛擬內(nèi)存的狀態(tài)(free, reserver, commit)和屬性。


            下面說下應(yīng)用層對程序內(nèi)存的訪問, 按照內(nèi)存的用途就可以大概劃分:
            Image: 主要是指二進(jìn)制模塊在內(nèi)存中存在方式, 比如Exe和Dll, 對應(yīng)的API比如LoadLibrary。
            Mapped file: 主要是指內(nèi)存映射文件, 可以用來快速的加載大文件 ,或者跨進(jìn)程共享內(nèi)存, 對應(yīng)的API比如 CreateFileMapping.
            Stack: 每個(gè)線程都有自己的堆棧, 包括用戶態(tài)堆棧和內(nèi)核堆棧,雖然堆棧內(nèi)存分配有大小限制, 但是非常高效,函數(shù)的局部變量都存在里面,程序的運(yùn)行過程(函數(shù)的調(diào)用過程)實(shí)際上是不停的壓棧和出棧的過程,大小一般默認(rèn)保留1M(參見線程堆棧是如何增長的)
            Heap: 系統(tǒng)有自己的堆管理器, 雖然效率堆內(nèi)存分配效率低, 但是沒有大小限制, 對應(yīng)的API比如new, malloc, HeapAlloc


            操作系統(tǒng)為我們訪問內(nèi)存提供了各種渠道,我們可以根據(jù)需要自己選擇, 由下往上可以分為:
            虛擬內(nèi)存: 對應(yīng)的API如VirtualAlloc(Ex), VirtualFree(Ex), VirtualLock, VirtualProtect, 通過這些API,我們可以直接分配(reserver, commit)大塊內(nèi)存( 4K頁面大小), 同時(shí)定義修改頁面屬性, 這是最高效的大內(nèi)存分配方式。
            Win32 堆內(nèi)存: 對應(yīng)的API如HeapCreate, HeapAlloc, 堆內(nèi)存建立在虛擬內(nèi)存之上,很多時(shí)候我們不需要虛擬內(nèi)存的大塊內(nèi)存,只需要小塊內(nèi)存,操作系統(tǒng)通過堆管理器幫我們解決了這個(gè)問題。每個(gè)進(jìn)程啟動時(shí)系統(tǒng)都會創(chuàng)建一個(gè)默認(rèn)堆,同時(shí)我們也可以創(chuàng)建自己的私有堆, 不同模塊之間是否共享同一個(gè)CRT堆取決于模塊的編譯選項(xiàng),(參見基于WinDbg的內(nèi)存泄漏分析
            CRT 堆內(nèi)存:C/C++代碼中我們最常用的內(nèi)存分配方式是malloc和new, 通常情況下malloc只負(fù)責(zé)內(nèi)存分配, 而new在調(diào)用malloc分配內(nèi)存的同時(shí)還有在分配的內(nèi)存上構(gòu)造對象的功能。至于malloc的實(shí)現(xiàn)方式, 不同的編譯器廠商會有不同的實(shí)現(xiàn), 有些可能是通過Win32堆實(shí)現(xiàn),也可能是通過虛擬內(nèi)存API直接實(shí)現(xiàn)。


            思考為什么有了虛擬內(nèi)存API和Win32堆API,還要有CRT堆API?
            軟件工程里一條比較經(jīng)典的話是: 任何問題都可以加一個(gè)間接層加以解決。操作系統(tǒng)提供的API都是平臺相關(guān)的, 通過CRT這個(gè)間接層實(shí)現(xiàn)了平臺無關(guān), 同時(shí)我們可以在這個(gè)間接層上做很多事情, 比如內(nèi)存泄漏跟蹤, 實(shí)現(xiàn)自己的內(nèi)存池等。


            如果我們直接調(diào)用虛擬內(nèi)存API分配內(nèi)存, 這種內(nèi)存屬于那種類型?
            實(shí)際上按照VMMap的說法, 內(nèi)存類型還有更多: Image, Mapped File, Shareable, Heap, Managed Heap, Stack, Private Data, Page Table, Unusable, Free.
            直接通過VirtualAlloc分配的內(nèi)存不屬于Heap, 應(yīng)該屬于Private Data.
            posted on 2016-04-07 21:45 Richard Wei 閱讀(3333) 評論(1)  編輯 收藏 引用 所屬分類: windows desktop

            FeedBack:
            # re: Windows內(nèi)存小結(jié)
            2016-04-08 21:31 | anna
            任何問題都可以加一個(gè)間接層加以解決!  回復(fù)  更多評論
              
            国内精品伊人久久久久妇| 日韩精品国产自在久久现线拍 | jizzjizz国产精品久久| 国产精品美女久久久m| 久久精品无码一区二区三区日韩 | 99久久国产亚洲高清观看2024| 91精品观看91久久久久久| 午夜精品久久久久久影视777| 国产精品久久午夜夜伦鲁鲁| 久久有码中文字幕| 久久er国产精品免费观看2| 久久成人小视频| 91麻精品国产91久久久久| 亚洲综合伊人久久综合| 国产成人香蕉久久久久| 久久久久久无码Av成人影院 | 精品国产乱码久久久久久人妻| 97热久久免费频精品99| 亚洲国产日韩欧美久久| 51久久夜色精品国产| 狠狠色婷婷久久综合频道日韩 | 四虎国产精品成人免费久久| 99久久精品国产麻豆| 亚洲日韩中文无码久久| 人妻无码久久精品| 办公室久久精品| 99久久综合狠狠综合久久止| 色欲久久久天天天综合网精品| 久久亚洲精品国产亚洲老地址| 久久精品国产亚洲av瑜伽| 91麻豆精品国产91久久久久久| 91久久婷婷国产综合精品青草 | 色欲久久久天天天综合网精品 | 久久久久久国产a免费观看黄色大片| 99久久精品免费看国产| 国内精品久久久久影院免费| 97久久久久人妻精品专区 | 日韩欧美亚洲综合久久影院d3| 国产精品99精品久久免费| 久久精品人人做人人爽电影蜜月| 久久久久女人精品毛片|