與GC相關的效能計數器

2022-03-05 21:05:27 字數 2830 閱讀 8016

如果遇到了效能問題,在使用debug之前分析問題較為不錯的乙個工具就是perfmon.解決問題最好的方法是思考,這也是熊力大哥在其書中一直在強調的.

cpu占用高,記憶體占用不高.

cpu和記憶體占用都比較高

cpu和記憶體占用都不高,但是**響應很慢

開啟perfmon找到.net clr memory後下面有好幾個counter,從哪個開始看呢?

1) % time in gc

這 個值是說從上一次gc結束到當前這次gc的時間的百分比. 比如上次gc結束時經歷了100w個迴圈,當前的gc消耗是50w個迴圈,這個計數器的值就是50%. 看perfmon的各個counter來推測究竟是什麼問題,主要有兩類情況,第一類需要看counter到變化趨勢,第二類需要看到是counter到 值.這裡對待第2類情況引入乙個"健康值"的概念.當然這些只是大方向上來說到,並不是100%到準確的適應大多數情況.

那麼這個值為多少合適呢? 一般來說如果這個值》50%了我們應該去檢查一下託管堆的問題.如果這個值不大,沒有太大的必要去優化程式了.

2)allocated bytes/sec

如 果認為在gc上花費的時間太多了,接下來應該看看allocated bytes/sec這個counter,它顯示了分配速率.需要注意到是這個counter到值在分配速率很低的情況下其實是不準確的,這個值只有在每次 gc開始的時候才會被更新,如果perfmon到取樣頻率(預設是1秒)大於gc的頻率的時候,這個值就不太容易說明問題了。

當有分配請求不能被完成時,會觸發gc:

gen0滿了,不能滿足最後一次的小物件的分配請求

loh滿了,不能滿足最後一次的大物件分配請求

所以當gc開始的時候會更新該計數器到值——將gen0和loh想加的和加到這個值上,然後與上一次的值相加再除以時間間隔。得到的就是這個分配速率。

舉 個例子:預設情況下perfmon1秒更新一次資料,在第1秒gen0 gc因為需要分配100k而觸發,所以再第1秒末這個值是(100k-0k)/1sec,是100k/sec。在第2秒沒有gc發生,記錄的值還是 100k,那麼第2秒末該值就是(100k-100k)/1sec,是0k/sec,第3秒gen0 gc又被觸發總共被分配了200k,所以在第3秒末的時候這個值是(200k-100k)/1sec,是100k/sec。

從上面到例子能看到如果說gc發生的不是非常頻繁的話這個值應該是0k/sec的。

3)large object heap size

這個值只是記錄在loh裡的bytes。

ok。 到這一步為主,我們可以看出導致gc做大量工作的乙個關鍵因素就是較高的分配速率。大家都知道gc是分generation的,從gen0到gen2,如 果乙個物件在gen0到時候就死了,我們況且成它為「夭折」(die young),另一類生命力看似頑強但是到了gen2立刻掛掉的,我們稱之為「中年危機」(die at gen2)。

所以如果都在gc gen0完成後就結束工作了,花在gc上的時間百分比是不會高的。畢竟gen0到gc只會占用非常短暫的時間。

但是gen2的gc就不這樣了,它會從gen0到gen2,再加上loh的。loh的gc也是很消耗資源的工作,但是並沒有只針對lo的**,所以即使loh還有空間可供分配,但是gen2滿了,也會導致loh跟著一起遭殃。

通常來說這三個代的gc速率在100:10:1是不錯的。

4)# gen x collections

x到值為0,1和2。需要注意的一點是gen1會一次性的**gen0和gen1。

如果有大量的gen2上的gc,就意味著有大量的物件存活了太長時間,但是還沒長到他們要一直在gen2裡生存。如果看到了gc消耗了很多時間但是分配速率卻不高的話,最大的可能就是很多物件在不斷的從gen0到gen2被不斷的提公升。

5)promoted memory from gen 0/1和 promoted finalization - memory from gen 0

這三個值是看提公升(promotion)情況的。被finalization引發的物件的提公升要看後者,是不包括在前面兩個counter裡的。但是後者雖然說是from gen 0的,但是其實同時包含了gen0和gen1的。

這時可能出現一種最壞的情況:乙個物件存活了很久,最終被提公升到gen2,但是一進入gen2立刻就死掉了,也就是上述的「中年危機」。當遇到這個情況promoted memory from gen1到只是比較高的,而且有大量的gen2 gc。

需要注意到是當乙個finalizable的物件存活時,所以他引用的物件也都是存活的,promoted finalization-memory from gen0的計數器也包含了這些物件。

6)gen 1/2 heap size

當看到這些提公升相關的計數器的值比較高時,應該看看這兩個counter。他們的意思從名字就能看出。

需要注意gen 0 heap size到值是假的,它其實是乙個預算,指示下一次什麼時候進行gc的。

gen0和gen1都很小,從256k到幾兆。

7)# total committed bytes和# total reserved bytes

# total committed bytes= gen0 heap size + gen 1 heap size + gen 2 heap size + loh size

後者到值要比前者的值大.

8)# induce gc

如果看到這個值比較高那就比較慘了,檢查**中gc.collect()是不是呼叫了太多了.這種使用和設定iis檢測到memory漲到一定程度自動**一樣,都不是真正解決問題的方法.

效能計數器之CPU

processor processor time 閥值 處理器的閥值一般設為85 含義 這個計數器是處理器活動的主要指標。高數值並不一定是壞事,但是如果其他處理器相關的計數器 比如 privileged time 或者processor queue length 線性增加的話,高cpu使用率就值得調...

關於WCF的效能計數器

公司的專案的服務端採用wcf,現在使用者反應系統響應慢 其實系統高峰期頂多100個人在用 現在boss讓我查查效能的瓶頸在哪。由於wcf的配置檔案只自定義的 採用這樣的框架現在我在myservicehost.cs 這個類裡新增servicemodel.diagnostic.performanceco...

Windows效能計數器監控實踐

windows效能計數器 performance counter 是windows提供的一種系統功能,它能實時採集 分析系統內的應用程式 服務 驅動程式等的效能資料,以此來分析系統的瓶頸 監控元件的表現,最終幫助使用者對系統進行合理調優。市面上採集windows效能計數器指標的產品參差不齊,尤其在處...