<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      厚積薄發
      海納百川,有容乃大
      以前寫過一篇理解程序內存, 當時主要是針對用戶態,下面再稍微深入一點:


      我們以32位程序為例(不啟用AWE), 總共4G虛擬空間,其中低2G屬于用戶態, 高2G屬于操作系統內核, 每個程序都有自己的低2G用戶空間, 高2G內核空間是所有程序共享的。高2G內核空間中, 屬于同一Session的程序又共享相同的session空間:


      x86系統所有的內存以64K邊界粒度, 4K頁面大小分配。


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


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


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


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

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


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


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


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


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


      如果我們直接調用虛擬內存API分配內存, 這種內存屬于那種類型?
      實際上按照VMMap的說法, 內存類型還有更多: Image, Mapped File, Shareable, Heap, Managed Heap, Stack, Private Data, Page Table, Unusable, Free.
      直接通過VirtualAlloc分配的內存不屬于Heap, 應該屬于Private Data.
      posted on 2016-04-07 21:54  Richard Wei  閱讀(1548)  評論(0)    收藏  舉報

      主站蜘蛛池模板: 亚洲国产av剧一区二区三区 | 欧美精品一区二区三区中文字幕| 亚洲香蕉网久久综合影视| 成人片黄网站色大片免费| 日韩在线不卡免费视频一区| 亚洲综合无码一区二区三区不卡 | 国产天堂亚洲国产碰碰| 日韩精品一区二区三区激| 精品国产成人国产在线视| 欧美人与zoxxxx另类| 国产精品无码a∨麻豆| 亚洲一区二区三区十八禁| 丁香五月亚洲综合在线| 日本韩国日韩少妇熟女少妇| 亚洲精品美女一区二区| 安岳县| 丰满高跟丝袜老熟女久久| 18禁无遮挡啪啪无码网站破解版| 亚洲精品美女一区二区| 亚洲国产精品老熟女乱码| 亚洲欧美综合中文| 炉霍县| 麻豆一区二区三区精品视频| 亚洲一区二区av高清| 中国女人内谢69xxxx| 麻豆国产成人AV在线播放| 亚洲第一香蕉视频啪啪爽| 无码吃奶揉捏奶头高潮视频| 人妻出轨av中文字幕| 亚洲人成电影在线天堂色| 亚洲欧洲美洲在线观看| 午夜爽爽爽男女污污污网站| 国产精品福利自产拍久久| 久久久久久综合网天天| 亚洲av午夜福利精品一区二区| 日本亚洲一级中文字幕| av色国产色拍| 日韩一区二区三区一级片| 国语精品一区二区三区| 日韩午夜无码精品试看| 免费无码肉片在线观看|