內存詳解


前一篇文章介紹了任務管理器中關於內存的兩個重要概念:private和working set。但是內存遠不止那么簡單,下面我根據VMMap來詳細介紹一下內存的分類。

內存是一個很復雜的系統,其中的paging file,sharable memory,reserve和commit等概念使得要算清楚一個進程到底使用了多少內存幾乎成了不可能的事情了。

還好我們有VMMap這個工具,它用兩個緯度將內存進行了詳細的划分。

一個是縱向的緯度,也就是內存是從哪里來的。分為

  1. Image(可執行文件),
  2. Mapped file(由CreateFileMapping以文件作為back up)。
  3. Sharable(由CreateFileMapping以內存作為 back up)
  4. Private Data(由Virtual Alloc分配)
  5. Heap(由new,GlobalAlloc和HeapAlloc等分配)
  6. Stack(棧占用的控件)
  7. Page table(內核里面維護當前虛擬地址控件所需要的內存)
  8. Managed Heap(由.NET garbage collector分配和管理)

               

還有一個橫向的維護,分別被稱為:

 

  1. Size: 總體大小,包括了commit和沒有reservce的內存。如果這項和Committed不 一致,那么就是說有reserve的內存。
  2. Committed: committed的大小,包括Private內存和可共享的內存。
  3. Private:屬於當前進程的虛擬內存,指的是當你修改他時僅僅當前進程會受到影響。(copy-on-wirte屬性的頁面還沒被修改時也屬於此類)

以上實際上是虛擬內存(virtual memory)的概念,其中的內容可能被物理內存(physical memory)back up,也可能被Paging file back up。

而以下的幾個指標指的是物理內存:

  1. Total WS: 所有的working set,包括private working set和sharable working set。
  2. Private WS: private working set。僅屬於當前進程的working set。
  3. Sharable WS。可共享的working set。
  4. Shared WS。已經共享的working set,這個值應該是sharable working set的一部分或者全部。

 

為了更具體的了解這幾個指標,下面我們根據一些API的具體行為所產生的結果來觀察一下他們的含義。

 

New,GlobalAlloc and HeapAlloc:

受影響的是VMMap中的Heap行。

分配時占用的是Committed和Private列,working set不受影響。

當訪問時Total working set和Private Working Set跟着上升。

 

VirtualAlloc:

受影響的是VMMap中的Private Data行。

分配Reserve的data時,上升的是第一列Size,第二列Committed不變。

Commit時,上升的是Committed和Private列。Total Working Set列不變。

當訪問Commit的內存時,上升的是Total Working set 和Private Working set列。

DeCommit時,只有第一列size保持不變,Committed,Private和Working set列都下降。

Release時,第一列Size也下降。

 

Memory Based CreateFileMapping

這個file mapping不管有沒有命名,下面的行為都一樣。

受影響的是VMMap中的Sharable行。

調用CreateFileMapping時,不影響任何列,增加的只是系統的Total Commit Charge。

調用MapViewOfFile時,上升的是Size和Committed列。

當訪問這些map的數據時,上升的是Total Working Set和Sharable Working Set。

調用UnmapViewOfFile時,Size,Committee和Working set列都下降。

調用CloseHandle來關閉CreateFileMapping創建的handle時,不影響任何列, 但是減少了系統的Total Commit Charge。

 

共享狀態下的Memory based CreateFileMapping

需要注意的是這個file mapping命名了,並且是在同一個進程中打開兩次,以達到共享的目的。

受影響的是VMMap中的Sharable列。

調用第一個調用CreateFileMapping時,不影響任何列,增加的只是系統的Total Commit Charge。

調用MapViewOfFile時,上升的是Size和Committed列。

當訪問這些map的數據時,上升的是Total Working Set和Sharable Working Set。

以上行為跟前面一個Scenario完全一樣,下面要開始創建再次打開剛才創建的File mapping.

當用同樣的名字再次調用CreateFileMapping打開前面創建的file mapping時,系統的Total Commit Charge不受影響,也不影響VMMap中的任何列。

調用MapViewOfFile時,上升的是Size和Committed列。也就是說,上升第二次了。

當訪問這些map的數據時,上升的是Total Working Set和Sharable Working Set。也是上升第二次。

調用UnmapViewOfFile來ummap掉第二次打開的view,Size,,commmited和working set都下降一半。

調用UnmapViewOfFile來ummap掉第一次打開的view,Size,,commmited和working set都下降到初始狀態。

調用CloseHandle來關閉第二次打開的Handle,Total Commit charge不受影響。

調用CloseHandle來關閉第一次打開的Handle,Total Commit charge下降。

 

File Based CreateFileMapping

受影響的是Mapped File行。

調用CreateFileMapping時,沒有影響到VMMap中的任何列,並且跟Memory Based File mapping不一樣的是,Total Commit Charge也不受 影響,因為他是以File 作為back up的

調用MapViewOfFile時,上升的是Size和Committed列。跟Memory Based File mapping一樣的表現。

當訪問這些map的數據時,上升的是Total Working Set和Sharable Working Set。跟Memory Based File mapping一樣的表現。

調用UnmapViewOfFile時,Size,Committee和Working set列都下降。跟Memory Based File mapping一樣的表現。

調用CloseHandle來關閉CreateFileMapping創建的handle時,不影響任何列, 也不影響Total Commit Charge。

總結:file based和memory based不同點在於:

  1. File based影響是Mapped file行,memory based影響的是Sharable行。
  2. File based 不影響total commit charge, memory based 影響。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM