2011-02-24 63 views
1

我想知道一个方法运行时分配的内存总量。到目前为止,我有:如何查找方法分配的内存量?

GC.Collect() 
GC.WaitForPendingFinalizers() 
memStart = GC.GetTotalMemory(false) 
f() 
memEnd = GC.GetTotalMemory(false) 
print (memEnd - memStart) 

这似乎是工作不够好,简单的功能,但是当f分配这么多,这迫使一个集合,那么结果排除了已收集的对象。不仅如此,没有办法说明这种“溢出”发生了。

有没有简单的方法来做到这一点?不购买/安装/配置内存分析器?分配器/收集器的秒表就像是一个理想的东西。所以,我可以这样做:

sw = new GCStopwatch() 
sw.Start() 
f() 
sw.Stop() 
print sw.TotalBytesAllocated 
print sw.NumberOfCollections 
// etc 

我想要这个,所以我可以找出多少压力的方法是在垃圾收集器推杆。我的代码是从一个固定长度的字符串中读取数字,并使用Int32.Parse(s.Substring(4,6))的大量调用,我考虑通过引入ParseInt(String s, int startIndex, int length)来避免分配数以万计的子字符串,从而在原地进行解析。但这也是在其他场景中的一个很好的工具。

+1

如果'f'分配了很多小对象,从而导致了一个集合,并且很多这些对象被释放......好 - .NET内存系统运行良好,并且有一个主要假设 - 很多最近分配的对象可以被释放。换句话说,你为什么试图猜测分配器和垃圾收集器? – 2011-02-24 08:27:40

+0

@Damien:我不想以任何方式猜测或影响GC。我只想在一定时期内收集一些关于分配/收集的统计数据,即。一个轻量级的剖析类。 – petebu 2011-02-24 13:10:42

+0

@petebu - 我更关注你的最后一段,你正在考虑重写框架功能以避免分配这些子字符串。 – 2011-02-24 13:47:36

回答

0

我一直使用这些分析的性能计数器。不完美,但通常足够好。

GC.Collect() 
GC.WaitForPendingFinalizers() 

这两行不会等待垃圾收集器实际完成。无论如何,在函数调用期间可能会发生垃圾回收。将性能/时间作为优化来衡量可能会更好。

0

我知道你说过你不想使用内存分析器,但这正是一种有用的情况。只需下载ANTS Memory Profiler之类的东西,并使用14天的免费试用版即可。它应该给你一个相当即时的情况。