2013-04-04 52 views
1

目前我正在做我的工作,确定了C#项目的内存分析,如果有因为这种应用程序需要的任何泄漏,有接近100%的正常运行时间成为可能。我开始使用蚂蚁内存分析器7.4版,并注意到我的非托管内存随着时间的推移不断增长,即使我的托管内存不是。非托管堆.NET应用程序的大小

更多经过试验,我尝试了一个程序,什么也不做,但块上的Console.ReadLine()指令做了类似的分析。我运行了分析,并注意到同样的事情发生。我的非托管堆正在慢慢增长。实际上,它实际上只是在垃圾收集器被调用时(通过快照功能)而增长。现在为什么反复调用垃圾收集会导致非托管内存的不良增长?与ANTS有关吗?

我想用一些其他的工具,最好是像的WinDbg或SOS,以确定它认为我的非托管内存使用率。现在对我来说了解其中的内容并不重要 - 尽管这可能有助于长期调试。我只是试图确定当前正在运行的应用程序的非托管内存使用情况。我想看看这是否真的是蚂蚁的问题,或者是我对环境如何运作的误解。拥有某种.net,visual studio或windows工具可以为我提供有关我的流程的准确信息,这将有助于我解决这个问题。

+1

是你的代码是100%的C#,还是有一些C++/CLI或非托管C++? – 2013-04-04 14:31:25

+1

它是一个窗体项目吗? WindowsForm使用非托管窗口API来绘制对象 – Draykos 2013-04-04 14:32:54

+0

对不起,我完全忽略了这些重要信息。我没有明确使用任何非托管代码。代码有一些线程并使用一些.net套接字对象。它也作为控制台应用程序运行 - 其中没有winform或wpf组件。最后,即使当我嘲笑所有的.net网络对象并摆脱了我的线程 - 我仍然看到了这一点。另外请记住,对于只有一行阻止ReadLine()的简单应用程序,我也看到了这种行为。 – user2245290 2013-04-04 14:35:27

回答

0

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(); 
      } 
     } 
    } 
} 
+0

请举例。 – 2013-04-04 14:35:50

+0

@Robert是的,我知道。但我这样回答:答案。添加细节。添加示例。澄清。澄清。是语法纳粹。修复其他人的答案。获取代表。感觉像一个Skeet想要的。 – 2013-04-04 14:38:05

+0

仅发布帖子链接回复,风险降低,永远不会被删除,因为人不会重新检查您的答案,或者回复被删除。我猜你的选择。 – 2013-04-04 14:39:12

0

使用garbagge收集器分析器。如果存储桶2和3上的对象数多于1,则表明您没有正确管理您的非托管资源

+0

如果我的托管内存没有增长,并且蚂蚁确认没有在托管内存中创建新对象,那么这种方法是否可行,以确定有关我的非托管堆的任何内容? – user2245290 2013-04-04 14:47:28

1

AQTime来自SmartBear做了非常好的工作,可以在托管代码和非托管代码上进行内存分析。我的很多工作都在管理和非管理边界,我多次使用它来查找内存泄漏。

如果您正在处理大块非托管内存,请务必拨打GC.AddMemoryPressureGC.RemoveMemoryPressure以帮助GC一起工作。

+0

我没有明确地使用非托管内存。所有正在使用的非托管内存都是以我的名义完成的,这是由于当时我正在使用的任何.net托管对象。但是,谢谢,我会看看AQTime。 – user2245290 2013-04-04 14:49:56