How to debug the potential memory leak?

2019-02-14 12:37发布

问题:

I programed the windows service to do a routine work.

I InstallUtil it to windows service and it'will wake up and do something and then thread.sleep(5min)

The code is simple, but I've noticed a potential memory leak. I traced it using DOS tasklist and drew a chart:

Can I say that it's pretty clear there was memory leak, although so little.

My code is like below, Please help me to find the potential leak. Thanks.

    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);
            }
        }
    }

Edit: After using WinDbg @Russell suggested. What should I do to these classes?

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[]

回答1:

This is how I'd go about finding the memory leak:

1) Download WinDbg if you don't already have it. It's a really powerful (although difficult to use as it's complicated) debugger.

2) Run WinDbg and attach it to your process by pressing F6 and selecting your exe.

3) When it has attached type these commands: (followed by enter)

//this will load the managed extensions

.loadby sos clr

//this will dump the details of all your objects on the heap

!dumpheap -stat

//this will start the service again

g

Now wait a few minutes and type Ctrl+Break to break back into the service. Run the !Dumpheap -stat command again to find out what is on the heap now. If you have a memory leak (in managed code) then you will see one or more of your classes keep getting added to the heap over time. You now know what is being kept in memory so you know where to look for the problem in your code. You can work out what is holding references to the objects being leaked from within WinDbg if you like but it's a complicated process. If you decide to use WinDbg then you probably want to start by reading Tess's blog and doing the labs.



回答2:

you will need to use an Allocation Profiler to Detect Memory Leaks, there are some good profiler for that, i can recommend the AQTime (see this video)

And read: How to Locate Memory Leaks Using the Allocation Profiler

Maby this article can be helpfull too



回答3:

To find a memory leak, you should look at the performance counters on a long period of time. If you see the number of handles or total bytes in all heap growing without never decreasing, you have a real memory leak. Then, you can use for example profiling tools in visual studio to track the leak. There is also a tool from redgate which works quite well.



回答4:

Difficult to say, but I suspect this line in your while loop within DoWork:

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

Although jsonin only has scope within the while block, I would hazard that the Garbage Collector is taking its time to remove unwanted instances.