九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
追蹤內(nèi)存泄漏 | TechTarget IT專家網(wǎng)
追蹤內(nèi)存泄漏
【5/8/2005 9:47:52】 【Rico Mariani】 【TechTarget】
如果你認為你的內(nèi)存發(fā)生了泄漏現(xiàn)象,或你正在思索到底是什么東西占用了堆棧,你可以跟著我的步驟來解決困擾你和你的朋友們許久的問題。這個過程很簡單。
這些步驟將會讓你看到如何從發(fā)現(xiàn)一個可疑的內(nèi)存泄漏現(xiàn)象到得出某個特殊的對象引用的過程,這個引用正維持著該對象處于存活狀態(tài)。最后使用這些工具所得到的地址來查看資源的使用情況。
步驟1:運行進程并將你所好奇的進程的狀態(tài)浮現(xiàn)在你腦中確保選擇一個能在你頭腦中重現(xiàn)的情景,否則將不知道是否能在清理內(nèi)存泄漏工作中取得進展。
步驟2:使用tasklist命令來查找進程號
C:\>tasklist
Image Name                    PID Session Name     Session#    Mem Usage
========================= ====== ================ ======== ============
System Idle Process            0 RDP-Tcp#9               0         16 K
System                        4 RDP-Tcp#9                 0        112 K
smss.exe                    624 RDP-Tcp#9                0        252 K
...etc...
ShowFormComplex.exe        4496 RDP-Tcp#9     0     20,708 K
tasklist.exe                  3636 RDP-Tcp#9        0      4,180 K
大家可以看到我的進程號#4496
步驟3:使用VADump命令來得到進程的摘要
C:\>vadump -sop 4496
Category                   Total        Private  Shareable    Shared
Pages    KBytes    KBytes     KBytes    KBytes
Page Table Pages      35       140       140       0         0
Other System            15        60        60         0         0
Code/StaticData       4596   18384    4020     3376   10988
Heap                    215       860       860       0         0
Stack                    30       120       120         0         0
Teb                       4        16         16         0         0
Mapped Data          129      516         0        24       492
Other Data             157       628       624         4         0
Total Modules          4596    18384    4020      3376    10988
Total Dynamic Data  535      2140      1620        28       492
Total System             50       200       200         0         0
Grand Total Working Set 5181  20724  5840      3404     11480
大家可以看到最大代碼量的進程(18384k)
絕大多數(shù)CLR所使用的資源都處于”Other Data”下----這是因為GC Heap直接被VirtualAlloc進行分配 -- Other Data不會經(jīng)過規(guī)則的窗口堆棧。同樣這種所謂的”loader heaps”也不經(jīng)過規(guī)則的窗口堆棧,loader heaps存放類型信息和被jit處理的代碼。大部分傳統(tǒng)的”Heap”分配都是從正運行的任何未被管理的進程中得到的。這就是帶有控制管道的winform應(yīng)用程序,因此就存在與這些東西相關(guān)的存儲塊。
這兒并沒有太多的”Other Data”,因此堆棧狀態(tài)還是比較正常的。讓我繼續(xù)查看詳細的CLR內(nèi)存使用情況。
步驟4:使用windbg來裝載SOS
C:\> windbg -p 4496
調(diào)試器使用這個命令來裝載擴展DLL
0:004> .loadby sos mscorwks
這告訴調(diào)試器在裝載mscorwks.dll的地方對擴展”sos.dll”進行裝載。那樣可以保證你獲得SOS的正確版本(這個文件應(yīng)該與你正在使用的mscorwks文件相匹配)。
步驟5:獲取CLR內(nèi)存信息
這個命令用于顯示我們所分配的內(nèi)存信息。你所得到的輸出信息可能和我的不一樣,這主要取決于你所用的版本。但對一個簡單的應(yīng)用程序來說,你將會得到加載器堆棧的兩個基本域結(jié)構(gòu)(他們維持著以排序方式進行共享的對象)和存儲器的第一個真實應(yīng)用程序域(Domain 1)。當然還有被jit處理的代碼。
0:004> !EEHeap
Loader Heap:
--------------------------------------
System Domain: 5e093770
...etc...
Total size: 0x8000(32768)bytes
--------------------------------------
Shared Domain: 5e093fa8
...etc...
Total size: 0xa000(40960)bytes
--------------------------------------
Domain 1: 14f0d0
...etc...
Total size: 0x18000(98304)bytes
--------------------------------------
Jit code heap:
LoaderCodeHeap: 02ef0000(10000:7000) Size: 0x7000(28672)bytes.
Total size: 0x7000(28672)bytes
--------------------------------------
Module Thunk heaps:
...etc...
Total size: 0x0(0)bytes
--------------------------------------
Module Lookup Table heaps:
...etc...
Total size: 0x0(0)bytes
--------------------------------------
Total LoaderHeap size: 0x31000(200704)bytes
我們可以看到在內(nèi)存被所加載的實體占用了200K,被jit處理的代碼占用了28K.
接下來是GC堆棧的輸出信息。
=======================================
Number of GC Heaps: 1
generation 0 starts at 0x00a61018
generation 1 starts at 0x00a6100c
generation 2 starts at 0x00a61000
ephemeral segment allocation context: none
segment    begin allocated     size
001b8630 7a8d0bbc  7a8f08d8 0x0001fd1c(130332)
001b4ac8 7b4f77e0  7b50dcc8 0x000164e8(91368)
00157690 02c10004  02c10010 0x0000000c(12)
00157610 5ba35728  5ba7c4a0 0x00046d78(290168)
00a60000 00a61000  00aac000 0x0004b000(307200)
Large object heap starts at 0x01a61000
segment    begin allocated     size
01a60000 01a61000  01a66d90 0x00005d90(23952)
Total Size   0xcdd18(843032)
------------------------------
GC Heap Size   0xcdd18(843032)
在你的屏幕上可能會有很多更小的堆棧片斷,這是因為我是在內(nèi)部調(diào)試構(gòu)造上進行試驗的,本來在轉(zhuǎn)儲時會出現(xiàn)很多象12字節(jié)的小片斷。這樣你就可以知道那些片斷究竟是什么?他們到底有多大?還可以計算出當前內(nèi)存的確切大小。
從上圖我們可以看到GC堆棧的大小為843K。而其他的數(shù)據(jù)共占了2M,其中CLR就占用了1M左右,剩下就是一些從winforms應(yīng)用程序分配出來的位圖
步驟6:轉(zhuǎn)儲GC堆棧統(tǒng)計數(shù)據(jù)
接下來我們需要知道在這個具體實例的堆棧中到底有些什么類型
0:004> !DumpHeap -stat
... sorted from smallest to biggest ... etc. etc...
7b586c7c      436     10464 System.Internal.Gdi.WindowsGraphics
5ba867ac      208     11648 System.Reflection.RuntimeMethodInfo
7b586898      627     12540 System.Internal.Gdi.DeviceContext
5baa4954      677     39992 System.Object[]
5ba25c9c     8593    561496 System.String
Total 17427 objects
注意,如果你不知道在你執(zhí)行這條命令之前GC是否已經(jīng)運行,那么以上數(shù)據(jù)中將可能會包括可達和不可達這兩種對象。而且在這張表中你還可以看到一些已終止的對象。有時,在執(zhí)行該命令之前強制運行GC來得到當前存活對象的內(nèi)存信息是很有用的。也可以通過在運行GC前后將內(nèi)存信息進行轉(zhuǎn)儲來判斷哪些類別的對象已死亡。
我們假設(shè)此時不應(yīng)該為208 System.Reflection.RuntimeMethodInfo對象分配內(nèi)存,即我們就可以認為這是一個內(nèi)存泄漏?,F(xiàn)在我們需要做的一件事就是使用CLR Profiler來查看這些對象是在哪里進行分配的 --所得到的信息將會充滿半個屏幕。但我們可以在該調(diào)試器中得到一些其他的重要信息。
步驟7:轉(zhuǎn)儲特殊類型的信息
我們可以使用一個簡單的命令來轉(zhuǎn)儲每一個包含給定字符類型的對象
0:004> !DumpHeap -type System.Reflection.RuntimeMethodInfo
Address       MT     Size
00a63da4 5baa62c0       32
00a63e04 5baa6174       20
00a63e2c 5ba867ac       56
00a63e64 5baa5fa8       16
00a63e88 5baa5fa8       16
00a63f24 5baa6174       20
00a63f4c 5ba867ac       56
00a63f84 5baa5fa8       16
etc. etc. etc.
total 630 objects
Statistics:
MT    Count TotalSize Class Name
5baa62c0        3        96 System.RuntimeType+RuntimeTypeCache+MemberInfoCache`1
[[System.Reflection.RuntimeMethodInfo, mscorlib]]
5baa5fa8      211      3376 System.Reflection.CerArrayList`1
[[System.Reflection.RuntimeMethodInfo, mscorlib]]
5baa6174      208      4160 System.Collections.Generic.List`1
[[System.Reflection.RuntimeMethodInfo, mscorlib]]
5ba867ac      208     11648 System.Reflection.RuntimeMethodInfo
Total 630 objects
注意,我們所需要的類型是System.Reflection.RuntimeMethodInfo,顯示的內(nèi)容中含有一個方法表,其中包括5ba867ac,它所對應(yīng)的都是一些56字節(jié)的對象?,F(xiàn)在我們就可以來研究他們,看看是什么讓他們保持存活狀態(tài)。
步驟8:確定可疑泄漏的根源
轉(zhuǎn)儲中有一行是
00a63e2c 5ba867ac       56
因此我們可以知道我們要找的對象所在的地址是00a63e2c。接下來看是什么讓他們保持存活狀態(tài)。
0:004> !gcroot 00a63e2c
Scan Thread 0 OSTHread 1598
Scan Thread 2 OSTHread 103c
DOMAIN(0014F0D0):
HANDLE(WeakLn):3f10f0:
Root:00a63d20(System.RuntimeType+RuntimeTypeCache)
->00a63da4(System.RuntimeType+RuntimeTypeCache+MemberInfoCache`1
[[System.Reflection.RuntimeMethodInfo,mscorlib]])
->00a63e88(System.Reflection.CerArrayList`1
[[System.Reflection.RuntimeMethodInfo, mscorlib]])
->00a63e98(System.Object[])
->00a63e2c(System.Reflection.RuntimeMethodInfo)
DOMAIN(0014F0D0):
HANDLE(Pinned):3f13ec:
Root:01a64b50(System.Object[])
->00a62f20(System.ComponentModel.WeakEventHandlerList)
->00a63fb4(System.ComponentModel.WeakEventHandlerList+ListEntry)
->00a63ec4(System.ComponentModel.WeakEventHandlerList+ListEntry)
->00aa5f6c(System.ComponentModel.WeakDelegateHolder)
->00a63e2c(System.Reflection.RuntimeMethodInfo)
在以上內(nèi)容中我加入了一些附加的行以方便我們閱讀。
Gcroot命令告訴你該對象是否可達,如果可達則告訴你如何從每個root到達該對象。這種轉(zhuǎn)儲將不會包含所有到達該對象的路徑,但至少包含一條可以找到該對象的路徑 – 通常這已經(jīng)足夠了。如果轉(zhuǎn)儲中出現(xiàn)了多條路徑,那么這些路徑都含有相同的尾部。如果該對象可達(說明該對象可能只有弱引用存在,因此在下一次查看時該對象就不會再出現(xiàn)了),你就應(yīng)該從剩下的引用中找到相關(guān)的線索。從那些引用中你就可以決定哪些指針需要指向空來釋放對象所占用的內(nèi)存。
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
內(nèi)存泄漏如何排查?
ESP32 官方文檔(五)嚴重錯誤
JDK的命令行工具
Java 堆內(nèi)存溢出梗概分析
C#的內(nèi)存管理:堆棧、托管堆與指針
深入淺出圖解C#堆與棧 C# Heap(ing) VS Stack(ing) 第四節(jié) 參數(shù)傳遞對堆棧的影響 1
更多類似文章 >>
生活服務(wù)
熱點新聞
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服