VMMap(檢視記憶體工具)

2022-08-05 13:54:25 字數 3762 閱讀 5306

這兩個指標在process explorer中叫做private bytes和working set。

而在vmmap中,他們則分別被叫做private和total working set。我這裡也用private和working set來稱呼他們。

他們經常被用來標識一個程序到底佔用了多少記憶體,你知道他們分別代表什麼嗎?

private指的是當你修改他時僅僅當前程序會受到影響。(copy-on-wirte屬性的頁面還沒被修改時也屬於此類)。這類一般包括heap,stack和image的copy-on-write的部分。private是虛擬記憶體的概念,其對應的記憶體可能被實體記憶體backup,也可能被paging file backup。比如用new來建立一個100m的記憶體時,private就增加100m,但是這塊記憶體在被訪問之前,實際上是paging file backup的,實體記憶體並沒有真正佔用。(win7下測試所得)

working set是指實體記憶體。但是這個實體記憶體既包括了屬於當前程序的私有實體記憶體(private working set)。也包括了可以共享的working set(sharable working set)。private working set 就是前面的private的一部分,private的另外一部分由paging file backup。

在vmmap中,還有一個概念是committed,它也是虛擬記憶體的概念,其實可以分為private的虛擬記憶體和可以共享的虛擬記憶體。而可以共享的虛擬記憶體的由實體記憶體backup的部分就是sharable working set。

所以:從私有和可共享的角度來看:

committed = private virtual memory + sharable virtual memory

從memory由什麼back up來看:

committed = memory backed by paging file + working set

private virtual memory = private working set + private memory backed by paging file

working set = private working set + sharable working set

上面介紹了工作管理員中關於記憶體的兩個重要概念:private和working set。但是記憶體遠不止那麼簡單,下面我根據vmmap來詳細介紹一下記憶體的分類。

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

還好我們有vmmap這個工具,它用兩個緯度將記憶體進行了詳細的劃分。

一個是縱向的緯度,也就是記憶體是從**來的。分為

image(可執行檔案),

private data(由virtual alloc分配)

heap(由new,globalalloc和heapalloc等分配)

stack(棧佔用的控制元件)

page table(核心裡面維護當前虛擬地址控制元件所需要的記憶體)

managed heap(由.net garbage collector分配和管理)

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

size: 總體大小,包括了commit和沒有reservce的記憶體。如果這項和committed不 一致,那麼就是說有reserve的記憶體。

committed: committed的大小,包括private記憶體和可共享的記憶體。

private:屬於當前程序的虛擬記憶體,指的是當你修改他時僅僅當前程序會受到影響。(copy-on-wirte屬性的頁面還沒被修改時也屬於此類)

以上實際上是虛擬記憶體(virtual memory)的概念,其中的內容可能被實體記憶體(physical memory)back up,也可能被paging file back up。

而以下的幾個指標指的是實體記憶體:

total ws: 所有的working set,包括private working set和sharable working set。

private ws: private working set。僅屬於當前程序的working set。

sharable ws。可共享的working set。

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也下降。

受影響的是vmmap中的sharable行。

呼叫mapviewoffile時,上升的是size和committed列。

當訪問這些map的資料時,上升的是total working set和sharable working set。

呼叫unmapviewoffile時,size,committee和working set列都下降。

受影響的是vmmap中的sharable列。

呼叫mapviewoffile時,上升的是size和committed列。

當訪問這些map的資料時,上升的是total working set和sharable working set。

呼叫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和memory based不同點在於:

file based 不影響total commit charge, memory based 影響。