如何调试潜在的内存泄漏?

时间:2011-12-15 08:42:19

标签: c# memory-leaks windows-services

我编写了Windows服务程序以进行日常工作。

InstallUtil它到Windows服务,它会唤醒并做一些事情,然后thread.sleep(5min)

代码很简单,但我注意到了潜在的内存泄漏。我使用DOS tasklist跟踪它并绘制了一个图表: enter image description here

我可以说很明显存在内存泄漏,尽管很少。

我的代码如下,请帮我找到潜在的泄漏。感谢。

    public partial class AutoReport : ServiceBase
    {
        int Time = Convert.ToInt32(AppSettings["Time"].ToString());
        private Utilities.RequestHelper requestHelper = new RequestHelper();

        public AutoReport()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            Thread thread = new Thread(new ParameterizedThreadStart(DoWork));
            thread.Start();
        }

        protected override void OnStop()
        {
        }

        public void DoWork(object data)
        {
            while (true)
            {
                string jsonOutStr = requestHelper.PostDataToUrl("{\"KeyString\":\"somestring\"}", "http://myurl.ashx");
                Thread.Sleep(Time);
            }
        }
    }

编辑:使用WinDbg后@Russell建议。我该怎么办这些课程?

MT  Count   TotalSize   ClassName
79330b24    1529    123096  System.String
793042f4    471 41952   System.Object[]
79332b54    337 8088    System.Collections.ArrayList
79333594    211 70600   System.Byte[]
79331ca4    199 3980    System.RuntimeType
7a5e9ea4    159 2544    System.Collections.Specialized.NameObjectCollectionBase+NameObjectEntry
79333274    143 30888   System.Collections.Hashtable+bucket[]
79333178    142 7952    System.Collections.Hashtable
79331754    121 57208   System.Char[]
7a5d8120    100 4000    System.Net.LazyAsyncResult
00d522e4    95  5320    System.Configuration.FactoryRecord
00d54d60    76  3952    System.Configuration.ConfigurationProperty
7a5df92c    74  2664    System.Net.CoreResponseData
7a5d8060    74  5032    System.Net.WebHeaderCollection
79332d70    73  876 System.Int32
79330c60    73  1460    System.Text.StringBuilder
79332e4c    72  2016    System.Collections.ArrayList+ArrayListEnumeratorSimple
7.93E+09    69  1380    Microsoft.Win32.SafeHandles.SafeTokenHandle
7a5e0d0c    53  1060    System.Net.HeaderInfo
7a5e4444    53  2120    System.Net.TimerThread+TimerNode
79330740    52  624 System.Object
7a5df1d0    50  2000    System.Net.AuthenticationState
7a5e031c    50  5800    System.Net.ConnectStream
7aa46f78    49  588 System.Net.ConnectStreamContext
793180f4    48  960 System.IntPtr[]

4 个答案:

答案 0 :(得分:5)

这就是我如何找到内存泄漏:

1)如果您还没有WinDbg,请下载labs。它是一个非常强大的(虽然很难使用,因为它很复杂)调试器。

2)运行WinDbg并按F6并选择你的exe。

将其附加到您的流程

3)当它附加了这些命令时:(后跟回车)

//这将加载托管扩展

.loadby sos clr

//这将转储堆上所有对象的详细信息

!dumpheap -stat

//这将再次启动服务

g

现在等待几分钟,然后输入Ctrl + Break以重新进入服务。再次运行!Dumpheap -stat命令以查找堆上的内容。如果您有内存泄漏(在托管代码中),那么您将看到一个或多个类随着时间的推移不断添加到堆中。您现在知道内存中保存了什么,以便您知道在代码中查找问题的位置。如果你愿意,你可以弄清楚在WinDbg中保存对被泄漏对象的引用,但这是一个复杂的过程。如果您决定使用WinDbg,那么您可能希望首先阅读Tess的博客并执行{{3}}。

答案 1 :(得分:1)

你需要使用Allocation Profiler来检测内存泄漏,有一些很好的分析器,我可以推荐AQTimesee this video

并阅读:How to Locate Memory Leaks Using the Allocation Profiler

Maby this article也可以提供帮助

答案 2 :(得分:0)

要查找内存泄漏,您应该在很长一段时间内查看performance counters。如果您看到所有堆中的句柄数或总字节数增长而从未减少,则会出现真正的内存泄漏。然后,您可以使用Visual Studio中的分析工具来跟踪泄漏。还有一个来自redgate的工具,效果很好。

答案 3 :(得分:0)

很难说,但我怀疑DoWork中的while循环中的这一行:

JsonIn jsonIn = new JsonIn { KeyString = "secretekeystring", };

虽然jsonin只在while块中有作用域,但我会担心垃圾收集器会花时间删除不需要的实例。