我目前正在尝试对一个c#项目进行内存分析,以确定是否有任何泄漏,因为这个应用程序需要尽可能接近100%的正常运行时间。我开始使用Ants Memory Profiler 7.4版本,并注意到我的非托管内存随着时间的推移而不断增长,即使我的托管内存没有增长。
在做了更多的实验之后,我尝试对一个除了阻塞Console.ReadLine()
指令之外什么都不做的程序做类似的分析。我做了分析,发现同样的事情发生了。我那堆没人管的东西在慢慢增加。实际上,它只在垃圾收集器被调用时才会增长(通过快照功能)。那么,为什么反复调用垃圾收集会导致非托管内存的不可忍受的增加呢?这和蚂蚁有关吗?
我想使用一些其他的工具,最好是像windbg或SOS之类的东西来确定它看到我的非托管内存使用情况。现在对我来说,知道它是什么并不重要——尽管从长远来看,这可能有助于调试。我只是想确定当前运行的应用程序的非托管内存使用情况。我想看看这到底是蚂蚁的问题,还是我对环境如何运作的误解。有一些。net, visual studio,或者windows工具给我关于我的过程的准确信息会帮助我做到这一点。
来自SmartBear的AQTime在托管和非托管代码上做了很好的内存分析。我的很多工作都是在托管和非托管边界,我已经多次使用它来查找内存泄漏。
如果您正在处理大块的非托管内存,请确保调用GC.AddMemoryPressure
和GC.RemoveMemoryPressure
来帮助GC进行。
使用垃圾收集器分析器。如果桶2和桶3上的对象多于1那么你没有正确管理未管理的资源
System.GC.GetTotalMemory(bool)可能是您正在寻找的。下面是来自链接的注释示例:
using System;
namespace GCCollectIntExample
{
class MyGCCollectClass
{
private const long maxGarbage = 1000;
static void Main()
{
MyGCCollectClass myGCCol = new MyGCCollectClass();
// Determine the maximum number of generations the system
// garbage collector currently supports.
Console.WriteLine("The highest generation is {0}", GC.MaxGeneration);
myGCCol.MakeSomeGarbage();
// Determine which generation myGCCol object is stored in.
Console.WriteLine("Generation: {0}", GC.GetGeneration(myGCCol));
// Determine the best available approximation of the number
// of bytes currently allocated in managed memory.
Console.WriteLine("Total Memory: {0}", GC.GetTotalMemory(false));
// Perform a collection of generation 0 only.
GC.Collect(0);
// Determine which generation myGCCol object is stored in.
Console.WriteLine("Generation: {0}", GC.GetGeneration(myGCCol));
Console.WriteLine("Total Memory: {0}", GC.GetTotalMemory(false));
// Perform a collection of all generations up to and including 2.
GC.Collect(2);
// Determine which generation myGCCol object is stored in.
Console.WriteLine("Generation: {0}", GC.GetGeneration(myGCCol));
Console.WriteLine("Total Memory: {0}", GC.GetTotalMemory(false));
Console.Read();
}
void MakeSomeGarbage()
{
Version vt;
for(int i = 0; i < maxGarbage; i++)
{
// Create objects and release them to fill up memory
// with unused objects.
vt = new Version();
}
}
}
}