(翻譯)How To: Use CLR Profiler
第一次翻譯對我而言比較長的E文,有很多不足之處,請見諒。(個人的習慣GC又做了名詞又做了名詞)
原文:http://msdn.microsoft.com/en-us/library/ms979205.aspx
概況
CLR Profiler 能讓你觀察一個進程托管堆和研究(investigate)垃圾回收機制的行為表現。使用該工具中不同的視圖,你能獲得關于你運用程序的執行,分配和內存消耗的有用信息。
CLR Profiler 不是一個分析問題的出發點。然而,它能幫助你驗證和隔離問題代碼并追蹤內存泄漏。使用CLR Profiler,你能了解代碼分配了多少內存,引起了多少垃圾回收和占用內存多久。
注:CLR Profiler 是一個使你的應用的執行比起正常情況下明顯(significantly)慢(有的地方是10-100倍)的插入式(intrusive)工具。它的設計目的不是在產品環境下使用的。
你必須知道的
CLR Profiler的主要功能是讓你明白你的應用在使用托管、GC堆時如何互相協作的(interact with).你能分析一些更為重要的信息:
*誰分配了一些什么在托管堆
*哪些對象在托管堆中存活(survive)了下來
*誰是對象的持有者
*GC在你的應用程序的生命周期中做了什么
分析的結構存放在日志文件中。你能通過CLR Profiler中的視圖菜單查看這些文件以不同的方式,展現出對應的圖表(corresponding graph)。表1列出了最為有用的視圖。
表1:CLR Profiler視圖
|
視圖 |
描述 |
|
Histogram Allocated Types |
給你一個高等級的視圖,它指出對象類型(分配的大小)在你的應用程序的生命周期內被分配的情況。這個視圖也顯示那些被分配在大對象堆(對象超過85KB)中的對象。 這個視圖允許你點擊圖標的各個部分,為了你能看見哪些方法分配了哪些對象。 |
|
Histogram Relocated Types |
顯示已被GC(重新)分配(位置)的對象,因為他們在一次GC后存活了下來(就是別人還引用他們) |
|
Objects By Address |
提供一個任意特定時間(at a given time)托管堆情況的圖片 |
|
Allocation Graph |
用圖表顯示調用的堆棧是如何分別的對象。你能使用的視圖有: *查看方法的分配成本(the cost of each alloction) *隔離你不期望的分配 *找出有可能過度分配的方法 |
|
Assemby,Module,Function,and Class Graph |
有4個非常相仿的視圖。他們允許你看哪些方法涉及到了哪些程序集、類、模塊、方法 |
|
Heap Graph |
顯示托管堆上所有對象,以及他們的關聯信息。 |
|
Call Graph |
使你查看哪些方法調用了哪些別的方法和多少頻率。 你能使用這個圖表摸索著了解類庫的調用成本并判定調用這個方法的需求量和哪些方法被調用。 |
|
Time Line |
顯示GC的在你的應用程序中的重新分配情況(就是那些么有被清楚的對象)。使用這個視圖去: *研究了解GC的行為 *判定在3代中有多少GC發生(0,1,2代),和發生頻率。 *判定哪些對象在GC后存活,被提升到了下一代。 你能選擇時間點或間隔(intervals),通過右擊去顯示在這個時間間隙內(interval)誰分配了內存。 |
|
Call Tree View |
提供一個你應用程序執行的視圖,它是基于文本按年代分級。使用這個視圖可以: *查看什么類型被分配及他們的大小 *查看哪些程序集因方法調用而被被加載 *分析終結(finalizer)的使用,和他們的執行次數 *識別(indentify)方法在哪些地方沒有使用"close"或"dispose",從而引發瓶頸。 *分析在你意料之外的分配。 |
Profiling Applications
在這節中,你將創建一個小的C#控制臺應用程序例子,并通過使用CLR Profiler了解這個應用程序。
Creating Sample Applications for Profiling
"Sample: ProfilerSample1" 和 "Sample: ProfileSample2."代碼如下
ProfilerSample1.cs
ProfilerSample2.cs
To create sample console applications for profiling
1.創建一個ProfilerSample文件夾去存放示例的代碼。
2.在ProfilerSample文件夾中,創建2個C#文件,名為ProfilerSample1.cs和ProfileSample2.cs。從“Sample:ProfilerSample1”和“Sample:ProfileSample2”中將代碼示例拷貝到文件中。
3.打開cmd命令窗口,找到ProfilerSample文件夾,并通過下面的命令編譯代碼。(注意設置環境變量)
csc /t:exe /out:ProfilerSample2.exe ProfilerSample2.cs
使用CLR Profiler去分析應用程序
在這節中,你將分析ProfilerSample1.exe。
To use CLR Profiler to profile the application
1.打開CLR Profiler(CLRProfiler.exe).
2.確保下列選項已經勾選:
*Profiling active
*Allocations
*Calls
2.點擊Start Application。
3.在打開的窗口中,找到(navigate to)你保存示例代碼ProfilerSample文件夾所在位置,并選擇profilersample1.exe應用程序。
4.Interact with the application as needed and then close the application.
分析ASP.NET 應用程序
通過下面的步驟去分析asp.net應用程序
1.啟動CLR Profiler。
2.確保下列選項已經勾選:
*Profiling active
*Allocations
*Calls
3.在File菜單中點擊Profile ASP.NET。
CLR Profiler 完全關閉互聯網信息服務(internet infomation services ,iis),添加那些需要分析的環境變量(environment vaiables),重啟iis。CLR Profiler然后提示(prompt)你加載ASP.NET應用程序和等待ASP.NET工作京城啟動。
4.使用MS的IE瀏覽你所想分析的ASP.NET應用程序。你總能運行你的Web應用程序通過客戶端工具,如Microsoft Application Center Test(ACT,http://msdn.microsoft.com/en-us/library/aa287452.aspx.)。
5.當你已完成應用程序的運行,請點擊CLR Profiler窗口中的 Kill ASP.NET。CLR Profiler關閉IIS,移除環境變量,重啟IIS。
注意:有時候工具的當前版本不能對第4步頁面的加載做出反映。如果出現這個問題,試著改變ASP.NET進程級別(identity)至System在machine.config中的<ProcessModel>中。你完成分析你的應用程序后,確保你改變的應用程序級別再該回到Machine。
識別通常的GC問題(issues)
你能使用CLR Profiler.exe去識別并使與GC有關的問題隔離。
這些包括以下的內存消耗(consumption)問題:
*過度(Excessive)分配
*未知分配
*內存泄漏(leak)
他們總包括以下GC問題:
*過度收集
*長期存在(Long-lived)的對象
*執行GC所花的時間百分比
注意:更多關于使用CLR Profiler解決通常GC問題的詳細信息,請看CLRProfiler.doc中的"Common Garbage Collection Problems and How They are Reflected In These Views" ,它在安裝CLR Profiler文件夾的位置。
識別你的應用程序在哪分配了內存
你想去處理內存消耗問題,那么知道應用程序在哪做了內存分配是非常重要的。
識別你的應用程序哪分配了內存,有下面幾個步驟:
1.在CLR Profiler中啟動示例程序。
2.分析內存的分配類型。
3.判定誰分配了內存。
4.評估(evaluate)你能減少那些分配。
第一步:在CLR Profiler中啟動示例程序。
打開CLR Profiler并運行你先前(earlier)所創建的ProfilerSample1.exe應用程序。
第二步:分析內存的分配類型
在View菜單上,點擊Histogram Allocated Types。CLR Profiler 顯示一個類型于圖1的窗口。
圖1:
![]()
這個圖表顯示了在應用程序運行期間已被分配的對象。在這個例子中,大約2GB的對象被分配,幾乎都是字符串。原因是當你在示例代碼的方法中操作字符串時,.net分配一個新的字符串空間,拷貝老的并相加組成新的存放進去。(這句話的意思就是當你申明string str="";后你執行str+="new";時先前的str=""所在的空間還是在那,str+="new",是一個新的內存空間,它存放的是""+"new"的結果。)
使用Higtogram Allocated Tyoes視圖查看那些大對象(超過85k的)堆分配。你能選擇左邊特定的柱形條或右邊方格,并通過右擊他們查看是誰分配了這些內存。顯示了一個新的視圖,它展現給你一個在你應用程序運行周期內這些對象被誰分配的高級視圖。
第三步:Determine Who is Allocating the Memory
在View菜單中,點擊Allocation Graph。你也可以通過點擊如圖1所示的那個視圖中的某一個柱形條,右擊show who allocated。點擊這個菜單項顯示關于所選分配的特定詳細內容,而不是所有分配。(這句話說的應該是圖2視圖中的一個個小項)CLR Profiler 顯示的圖標如圖2所示。
視圖2:
![]()
在這個例子中,你能看見幾乎所有的(nearly all of)內存從string.Concat方法處所分配的情況。
Allocation Graph視圖能使你:
*看見每個方法的內存分配成本。
*分析那些出乎你意料的分配。
*比較做了相同工作的不同方法。
第四步:Evaluate What You Can Do to Reduce the Allocations
現在你知道你的應用程序在哪分配了內存,評估你能否減少(reduce)這些內存的消耗(consumption)。在這個例子中,一個選擇(option)是使用StringBuilder而不是使用string的拼接(concatenation)。
分析你的應用程序的(內存)分配情況
你的應用程序的(內存)分配情況告訴你,對象分配在什么位置,對象的生命周期,GC的行為。輕而易舉(walk through)的得知,應用程序持有的對象(和內存)是否比起通常情況下更長。再來看看ProfilerSample2.exe示例。
分析你的應用程序分配情況,通過以下步驟:
1.在CLR Profiler中運行示例程序。
2.識別長期存在的對象。(Identify long-lived objects.)
3.分析GC在你的應用程序中的行為。
4.評估是否可以減少對象的生命周期和如何減少。
第一步:Run CLR Profiler on the Sample Application
啟動CLR Profiler和運行ProfilerSample2.exe程序。
第二步:Identify Long-Lived Objects
示例代碼分配了100000個SolidBrush對象和一些string,導致總的分配約9MB。這個分配絕大多數是SolidBrush對象。通過選擇Histogram Resallocated Types 視圖,你能看見大約4MB內存因SolidBrush對象被再分配(reallocate).這個信息指出(indicate),SolidBrush對象在GC后未被清楚,并被提升到了更好的(GC)代。
判定什么類型的對象被提升和這些對象共計使用了多少內存,可以點擊View菜單的Objects by Address。如圖3所示:
圖3:
![]()
注意1,2代幾乎由SolidBrush對象組成。
第三步:Analyze GC Behavior over the Lifetime of Your Application
點擊VIew菜單上的Time Line產看更多詳細信息。設置縱坐標(Vertical Scales)為5,橫坐標(Horizontal Scales)為1,當滑輪向右移動,你應該看見一個類似圖4的窗口。
圖4:
![]()
在圖中,你能看見一個“雙鋸齒”的樣式。GC0代去掉(get rid of)的字符串,但保留(retain)brushes(換句話說,brushes在收集中存活了下來)。不久,GC1代清楚了brushes。
雙鋸齒樣式指示GC0代未能回收(reclaim)所有的內存,對象被更高的代所收集。
在這點上,你能看見那些在GC中存活下來的對象,并且你需要研究他們。首先一種肯能研究領域是SolidBrush終結(finalizer).
在工具的主菜單上,單擊Call Tree 打開一個調用的樹。查看finalizers列的調用情況,通過查找線程表直到找到finalizer線程。(我的CallTree窗口是自己通過鼠標拉大的,不看是很小的個窗口)
這個樹顯示NATIVE FUNCTION(UNKNOW ARGUMENTS)已觸發了總共1000234次調用。
因為對象么有被清楚直到finalizer線程啟動,對象無法作為一個被提升的結果收集。圖5顯示的就是一個類似樹圖的窗口。
圖5:
![]()
第四步:Evaluate Whether and How to Reduce Object Lifetimes
一旦你知道了那些對象是長期存在的,看看你是否能減少他們的生命周期。在這個例子中,你簡單的去確保SolidBrush被立刻Dispose在他們不再(on longer)需要的時候,通過把它包含在using 塊中。
附加的一些資源:
關于使用CLR Profiler解決通常有關CG問題的詳細信息,請看"Common Garbage Collection *Problems and How They are Reflected In These Views," 在CLRProfiler.doc,位于CLRProfiler.exe工具的安裝目錄中。
*學習關于托管代碼的更重要的性能因素(performance factor),請查看MSDN文章,"Writing High-Performance Managed Applications: A Primer," at http://msdn.microsoft.com/library/en-us/dndotnet/html/highperfmanagedapps.asp.
*關于GC的工作信息,和如何優化(optimize)GC,請查看MSDN article, "Garbage Collector Basics and Performance Hints," at http://msdn.microsoft.com/library/en-us/dndotnet/html/dotnetgcbasics.asp.
*關于CLR Profiler執行2個不同方法去解決同一個問題的比較和對照信息,請查看MSDN TV片段,"Profiling Managed Code with the CLR Profiler," at http://msdn.microsoft.com/msdntv/episode.aspx?xml=episodes/en/20030729CLRGN/manifest.xml.





}
}
浙公網安備 33010602011771號