﻿# 介紹好用工具：Process Explorer

[Windows Sysinternals](http://technet.microsoft.com/en-us/sysinternals/default.aspx) 是一套進階的系統管理工具，原本是由 Sysinternals Inc. 這家公司發產的產品（大多是免費的），可能因為做得太好了，在 2006 年 7 月時被微軟併購成為旗下的一套產品，這套產品中最有名的一個工具程式我覺得應該是 [Process Explorer](http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx)，他可以說是【Windows 工作管理員】的進階版，提供的資訊多到數不完，我想應該很多人都用過這個 [Process Explorer](http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx) 工具，但真的瞭解怎麼用的人我想應該不多吧，因為說明文件也沒寫什麼，我個人也沒有完全看的懂上面的所有欄位的真正意義（大概有上千個吧），我今天就說一些我經常在用的一些功能與查看有用資訊的技巧。

**1\. 程序之間的階層關係 & 判斷執行檔的類型**

![Process Explorer Screenshot](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/c809b9b70695dee42218-image_8.png)

如上圖，我用紅色框線框起來的地方就是指我的 notepad++.exe 程式是從 WinKey.exe 執行起來的，但你可能會想，如果我將 WinKey.exe 砍掉，會不會也將 notepad++.exe 也連帶砍掉呢？其實是不會的，而是 notepad++.exe 會自動拉高到自己為主程序。

另外，你也可以很容易的使用顏色來區別執行檔的類型，其中：

-   黃色：代表此程式是一個 .NET 的應用程式。例如說我用 [Process Explorer](http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx) 就發現原來 [Yahoo!奇摩輸入法](https://web.archive.org/web/20091001204217/http://tw.download.yahoo.com:80/keykey/) 就有支程式是用 .NET 寫成的。
-   紫色：代表此程式是一個 Pack (包裝) 過的程式，也就是說這個程式本身又被包了一層程式，意思也就是說該程式是被「修改過」的程式，並非為原本的程式喔！通常這種程式有兩種可能：
    1.  中毒的程式：病毒讓你的程式還是可以正常運作，讓你覺得程式沒問題，但是私底下可能「多做了一些事」讓你沒感覺。
    2.  壓縮過程式：知名的 [UPX](http://upx.sourceforge.net/) (the Ultimate Packer for eXecutables) 工具程式就是專門用來將你製作出來的執行檔壓縮過，讓你的執行檔變小又能正常執行的工具。
-   粉紅色：此程式為一個 Windows 服務。

至於其他的顏色所代表的意義，你可以從功能選單的 Options -> Configure Highlighting 查得完整的顏色定義，當然你也可以修改掉，如下圖：

    [![Process Explorer - Configure Highlighting](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/e7f66668b02aa0fafa18-image_thumb_2.png)](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/c17d44b01c003a5fe1f2-image_7.png)

**2\. 查看該程序(Process)到底開啟了哪些檔案或使用到哪些 DLL**

 ![查看該程序(Process)到底開啟了哪些檔案或使用到哪些 DLL](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/17ea3f362c4401fb6e7d-image_18.png)

如上圖，你可以點選功能選單的 View -> Show Lower Pane 開啟 Lower Pane（或按下 Ctrl + L 快速鍵）查看程序載入了哪些 DLLs 或開啟了哪些 [Handles](http://en.wikipedia.org/wiki/Handle_%28computing%29) (目錄, 檔案, 事件, 機碼, 執行緒, ..., etc. )

 ![Process Explorer - Show Lower Pane](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/565d3610364c9006ee89-image_31.png)

如上圖範例，我按下了 Ctrl + H 開啟 Handles View，你可以看到圖中的 KeyKeyServer.exe 開啟了一些檔案，以上圖為例我選取了 D:\\Program Files\\Yahoo!\\KeyKey\\zh-TW\\Preference.resources.dll 程式，這時如果你想要刪除這個檔就會被通知「刪除檔案或資料夾發生錯誤」的錯誤訊息（如下圖），如果真的想強制刪除的話，可以在該 File Handle 上按下右鍵選擇 Close Handle 強制關閉這個 Handle，你就可以正常刪除檔案了，不過你原有的程式就很有可能會出錯或中斷執行，我是不太建議這麼做。

[![刪除檔案或資料夾發生錯誤](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/efae977320c7a0596151-image_thumb_8.png)](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/37343a9cb87679891071-image_26.png)

3\. 查看完整的系統資訊

[![Process Explorer - System Information](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/57850e0cf16131d0f583-image_thumb_5.png)](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/d36d5e09b2d2e0f359e6-image_28.png)

當你按下功能選單的 View -> System Information 或按下 Ctrl + I 快速鍵就可以看到這個完整的系統資訊，有時後我們電腦變慢可能跟 CPU 或 Memory 無關，而是 Disk I/O 過高導致拖慢程式執行的速度，透過這個畫面就可以一目了然你整台主機的運作狀況。

**4\. 瞭解你的 .NET 應用程式的執行狀態**

有在寫 .NET 的人對這裡的技巧可能就會很有興趣了，我以 [SharpReader](http://www.sharpreader.net/) 為例說明如何查看 .NET 相關的資料。我先啟動 SharpReader 應用程式，然後在 [Process Explorer](http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx) 上雙擊 SharpReader.exe 出現 Properties 視窗，然後點選 .NET 頁籤。

![在 Process Explorer 上雙擊 SharpReader.exe 出現 Properties 視窗，然後點選 .NET 頁籤](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/ac752f6ddd6fb794dfd8-image_10.png)

你會看見第一個區塊是 AppDomains，他會列出該程序所建立的所有 AppDomain 清單。下方是 .NET Performance Objects 區塊，這裡你就可以選擇不同的效能物件，用以查看該 .NET 應用程式的各種狀態。

**.NET CLR Exceptions**

-   \# of Exceps Thrown：這個程式總共發生了幾次 Exceptions，當你用 try / catch 捕捉到例外事件時，每捉到一次這邊就會加 1，你要知道 Exception 對效能的影響是很大的，對單機程式來說或許沒什麼差別，但是對多人使用的程式（如：ASP.NET）在人多的時候就會有差別了！
-   Throw To Catch Depth / sec：代表他統計你的程式平均每秒捕捉到深度統計，因為 try / catch 是可以很多層的，我是不太知道算出這個數據有什麼意義，不過應該是數據越高越不好吧！

[![Process Explorer - .NET CLR Exceptions](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/f8c54c0b0427fac81223-image_thumb_1.png)](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/7e8d8806ac9b262ce367-image_12.png)

**.NET CLR Interop**

-   \# of CCWs：所謂的 CCW 是 COM Callable Wrapper 的縮寫，是指這個 .NET 程序中有幾個物件被封送(Marshaled)成 COM 物件。
-   \# of Stubs：代表這個 .NET 程序中有幾個成員(Members)被 Export 到 COM 物件供其他程式使用。
-   \# of marshalling：代表這個 .NET 程序中被封送(Marshaled)處理的總數。
-   \# of TLB imports / sec：所謂的 TLB 是指 [Type Library](https://classicvb.net/hardcore/) 的縮寫，也就是平均有多少型別(Type)被匯入此 .NET 程序。
-   \# of TLB exports / sec：平均有多少型別(Type)被匯出到 COM 物件。

![Process Explorer - .NET CLR Interop](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/d86bb0c87990b79064f9-image_15.png)

**.NET CLR Jit**

-   \# of Methods Jitted：代表到目前為止有多少方法(Methods)被編譯成機械碼(Machine Code 或 Native Code)。
-   \# of IL Bytes Jitted：有多少 MSIL 位元被轉譯成機械碼。
-   Total # of IL Bytes Jitted：總共有多少 MSIL 位元被轉譯成機械碼。
-   Standard Jit Failures：轉譯成機械碼失敗的次數。
-   % Time in Jit：轉譯成機械碼所佔的時間百分比（因為可能有些程式寫了很多動態編譯的程式碼）。

![Process Explorer - .NET CLR Jit](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/ab8b3df9ecbc5e97cca0-image_19.png)

**.NET CLR Memory**

這裡的物件就很重要了，雖然 .NET 有個很棒的自動記憶體管理機制，但並不代表你就可以完全不管，雖然再怎麼亂用也不會發生 memory leak 的問題，但卻很有可能會發生 OutOfMemoryException 例外狀況，或是因為資源回收器(GC, Garbage Collector)頻繁啟動而導致的程式執行效能降低的情況，因為每次資源回收器啟動時都會將程序中所有執行緒(Threads)凍結，以便讓 GC 檢查受管控的堆積(stack)。詳細的 GC 運作機制可參考 [大內高手專欄](http://www.microsoft.com/taiwan/msdn/columns/DoNet/) 的 [.NET 的自動記憶體管理](http://www.microsoft.com/taiwan/msdn/columns/DoNet/garbage_collection.htm) 文章、[.NET Framework記憶體回收機制](https://web.archive.org/web/20080601162227/http://www.ithome.com.tw:80/plog/index.php?op=ViewArticle&articleId=6564&blogId=620) 文章或 **[C# 精要 (C# Essentials)](http://tlsj.tenlong.com.tw/WebModule/BookSearch/bookSearchViewAction.do?isbn=9578247656&sid=7990)** 一書，有意想深耕 .NET 領域的人不能不瞭解 GC 的運作機制，當你瞭解之後就看的懂底下這些欄位的定義代表什麼了。

![Process Explorer - .NET CLR Memory](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/2e8de40582eb1367097b-image_23.png)

其實還有許多其他相關的物件我沒有介紹，老實說我也不是全部都懂，但是等你越瞭解 .NET 的核心，就越能瞭解這些 Counter 所代表的意義。

其他相關連結：

-   [Profiling .NET Applications: Part 1](http://www.informit.com/articles/article.aspx?p=25313)
-   [Profiling .NET Applications: Part 2](http://www.informit.com/articles/article.aspx?p=25359)
-   [Profiling .NET Applications: Part 3](http://www.informit.com/articles/article.aspx?p=25360)
