2011-11-22 49 views
4

讓我感到震驚的是,如果一個應用程序可以定期掃描垃圾收集器中第二代或大型對象堆中的對象,並且看看它是否能夠找到真正流行的東西很長時間/永遠。其背後的一般理念是,如果多個集合存在相同的事件(通過弱引用跟蹤它們,以便分析它的行爲不會使其保留),應用程序可以確定潛在的對象是資源泄漏。我可以找到方法來詢問特定對象在哪一代,我可以找到非託管代碼或調試工具的API來調查託管堆,但我真正想要的是一個託管調用,以便爲我提供某種類型的數據結構指定代中的對象。我可以找出一代垃圾收集器中的所有對象嗎?

我是否有希望找到這樣的東西,或者我正在尋找一些不存在的東西?

從理論上講,可能需要調出調試器應用程序的實例並解析結果或其他內容,但我希望它在低負載時運行在實時Web服務器上,但我不確定ops會希望我附加一個調試器,即使這是可能的:)

回答

2

最近在Objective-C的土地上使用類似的工具,您可能需要尋找一個堆積工具。一個heapshot工具會爲你的堆取快照,從中建立一個內存圖並試圖找出哪些內存是根源以及在哪裏。這很大程度上與垃圾收集器發現收集哪些對象的方式類似。

通常情況下,heapshot工具允許您在不同時間拍攝堆的快照,並比較哪些內存已經生根,哪些對象佔用了該空間。單聲道堆積https://github.com/mono/heap-shot似乎是一個很好的起點,雖然我沒有個人使用它。 JetBrains dotTrace Memory在過去已經有了很好的結果。不幸的是,這兩種工具都不會向您顯示對象所處的世代,但它們可以跟蹤對象的身份,有時甚至可以跨越快照。如果你發現一個物體存在多個集合,它可能會生活在更高一代。確切的一代是實現,運行時和環境特定的。

其他內存分析器當然存在。 Microsoft CLR上的一個非常好的工具是WinDbg和SOS擴展。這裏有一篇很好的msdn雜誌文章:http://msdn.microsoft.com/en-us/magazine/cc163528.aspx,我發現苔絲來自(奇妙地命名)「如果打破它,修復它你應該」博客也有很棒的內容。 http://blogs.msdn.com/b/tess/

關於堆結構和GC代的一些常規信息可以通過一組性能計數器檢索到,文檔編號爲http://msdn.microsoft.com/en-us/library/x2tyfybc.aspx

+0

感謝您的想法。我會盡量抽出一些時間來通過堆放式拖網。它希望與它正在查看的應用程序分開使用,而不是它的一部分(請參閱命令行:mono --profile = heap-shot MyProgram.exe),但可能會使用一些技巧。 windbg的東西和whatnot是我迄今爲止所看到的,絕對是在運行的應用程序之外:( – eviltobz