使用PrefView監測.NET程式效能(一):Event Trace for Windows
前言:
在日常專案開發中,我們時不時會遇到程式佔用了很高CPU的情況,可能是程式裡某些未經優化的程式碼或者Bug,或者是程式執行壓力太大。無論是什麼原因,我們希望總希望能看到到底是哪個方法佔用瞭如此高的CPU。
微軟為我們提供了很多效能診斷工具來達到此目的。例如在Visual Studio 2017中的效能查探器,Windows SDK中的Windows Performance Recorder (WPR) 和Windows Performance Analyzer (WPA),XPerf,當然,還有這篇部落格介紹的PrefView。
但在介紹PrefView的使用前,有一個在Windows系統及應用程式效能這個主題上扮演重要角色的技術必須被提及,這就是Event Trace for Windows (ETW)。事實上,上邊提及到的效能分析工具都是基於ETW來實現的。
什麼是ETW
在 ofollow,noindex">微軟上的解釋 中,ETW是自Windows 2000 推出的"核心級"的事件日誌實現。通過記錄系統及應用程式中各類事件日誌,可以監測和分析系統及程式的執行細節,例如CPU使用率,.NET程式的GC狀況等。ETW的日誌裡,包含著非常多的有用資訊,例如程序/執行緒資訊,上下文切換,各種I/O資訊,程式執行時的時間節點,甚至是函式呼叫等資訊。通過對日誌資料進行實時採集,或者分析事件日誌記錄檔案(.etl檔案),就能輕易地檢測和分析系統和程式的執行狀況和效能瓶頸,而更為難得的是,ETW的效能還非常的高,據說可以達到 每秒寫入20W條記錄,而僅佔用5%的CPU。
Windows除了在系統核心及系統元件自帶了大量事件日誌,ETW還為開發者提供程式設計介面(在 System.Diagnostics.Eventing 名稱空間下),允許開發人員在專案中實現自己的事件跟蹤,或者像使用log4net一樣,將系統自定義的日誌記錄到ETW裡面。這點不在這裡展開了,有興趣的可以參考Artech的文章: 如何利用ETW(Event Tracing for Windows)記錄日誌
但話說回來,我曾經也嘗試過在專案了使用ETW,但感覺在一般專案開發中,還是使用Log4net和nlog這些日誌框架較為合適,畢竟一般來說業務系統的日誌是給人看的,而ETW的日誌資料是二進位制形式儲存的,更偏向於給日誌消費者用的,肉眼在看起來並不那麼方便,而且log4net/nlog更合適系統的業務場景的日誌使用。ETW還是作為系統性能分析手段比較適合。關於這個可以 參考這裡
ETW VS 效能監視器
或者有人會問,Windows裡已經提供了強大的效能監視器(Perfmon.exe),和資源監視器(順便說下,資源監視器也是基於ETW實現的。 參考這裡 ),為什麼還需要ETW和其他基於它的工具?例如使用效能監視器,新增各種效能計數器,也可以將系統在執行時的方方面面的效能資料呈現出來,那ETW及PrefView還有什麼存在意義?
一個非常明顯的理由就是,ETW的日誌儲存著非常詳細的程式執行資料。利用PrefView等工具,你可以看到具體一個程序載入資訊,執行緒的執行資訊,函式的呼叫樹,和執行時間,執行堆疊,CPU執行時間等等資訊,而效能監視器只能提供各個效能指標的資料,但並不能具體地展示哪個程式引起了具體的效能問題。通常我們可以配合效能監視器和ETW相關工具的使用,可以全方位的瞭解系統的效能狀況,並且可以直觀地看到具體是那些函式導致了效能問題,達到知其然同時知其所以然的效果。
第二個理由便是,ETW日誌的速度比效能監視器要快,可以在生產環境中自由地獲取執行資料而不影響伺服器執行。但效能監視器也是即開即用,所以我覺得這點對我來說意義不太大。
.ETL檔案
.etl檔案是ETW的日誌檔案擴。當使用PrefView等工具捕獲系統日誌後,便會生成此類檔案。使用PrefView等ETW的分析工具,可以對檔案內的日誌進行各種統計與分析操作。而如果只想單純地看日誌內容,可以使用Microsoft Message Analyzer開啟檔案。
參考資料:
ETW (Event Tracing For Windows) – what it is and useful tools
Inside Event Tracing for Windows
Logging ETW events in C#: System.Diagnostics.Tracing.EventSource