3

I have an application which does a bunch of text parsing. After each pass it spits out some info into a database and clears out all the internal state.

My issue is the memeory allocated in Windows Task Mgr / Resource Monitor keeps growing and growing. I've done some profile using .Net Mem Profiler and it looks like it should be going down. Here is a screen shot from the profiler:

enter image description here

But in the Task Mgr after each pass the memory private working set increases. I'd like for the memory to grow as its used and then return to a normal level after each pass, that way I could keep this thing running.

Any advice on what to look for or any ideas what causes this?

Luke Belbina
  • 5,708
  • 12
  • 52
  • 75
  • 2
    Have you had any problem with actually running out of memory? Or is this just preemptive worry? :) .net likes to hold on to memory for a while...i'm not seeing anything too unusual here. Unless it's actually causing an issue, i wouldn't worry too much about it. – cHao Mar 23 '12 at 23:40
  • I have big import jobs that use a few gigs of memory before they aggregate it and put it into SQL. After doing a few of those it ends up eating all the memory on the system and stops working. – Luke Belbina Mar 23 '12 at 23:55
  • Can you post the trace showing heap utilization in each generation and the instances in the heap? It will be easier to test if you a use a small sample data for testing and compare the memory snapshot after each pass. – Devendra D. Chavan Mar 24 '12 at 06:53
  • Check if this helps: [Memory leaks in .NET](http://stackoverflow.com/questions/20386/memory-leaks-in-net) – Devendra D. Chavan Mar 24 '12 at 07:01
  • And [Reducing memory usage of .NET applications?](http://stackoverflow.com/questions/1343374/reducing-memory-usage-of-net-applications) – Devendra D. Chavan Mar 24 '12 at 07:10

5 Answers5

5

A few things to check for are:

  1. Event handlers keeping objects alive, make sure that if the object which subscribes to an event goes out of scope before the object publishing the event that it unsubscribes from the event to prevent the publishing object keep a reference to it.
  2. Make sure that you call dispose on any object which implements IDisposable. Generally speaking objects which implement IDisposable contains resources which need special tidy up.
  3. If you reference any com objects, make sure you release them properly.

You shouldn't ever have to call GC.Collect() within production code.

Trevor Pilley
  • 16,156
  • 5
  • 44
  • 60
3

Task Mgr is not an accurate representation of the memory your application is actually using. Its more a representation of how much memory windows has allotted or planned for your application- if you app needs more, windows can expand this number, but if your app needs less, windows may not re-allocate this memory until another application actually needs it..

I think what you have above is a pretty accurate representation of what your application is actually doing (ie, its not leaking).

automagic
  • 1,067
  • 8
  • 10
  • Is there a way to either through .Net or a compile flag to tell windows to release memory for an app. When its running I don't mind it using a few gigs of memory as its actually needed. But once a job is processed, it would be nice to get that memory back from windows. – Luke Belbina Mar 23 '12 at 23:56
1

This forces .NET to collect all unused objects from memory, therefore reclaiming some of it:

GC.Collect();
GC.WaitForPendingFinalizers();
Diego
  • 18,035
  • 5
  • 62
  • 66
  • 2
    But it will not necessary release the memory to the OS, so private bytes may be unaffected. Remember the CLR acts as a memory manager for the managed app. – Brian Rasmussen Mar 23 '12 at 23:48
1

If you do have a memory leak, you can use the SOS debugging extension to try to find it. This article is also a very good example and a little more complete then what my answer will include.

You can use this in either VS or WinDbg, and the only difference is how you load the dll. For Visual Studio, first enable unmanaged debugging in the debug tab of your project's properties. When it comes time to load it, use .load SOS.dll in the Immediate Window. For WinDbg, either open the executable or attach to the process, and, to load it, use .loadby sos clr for .NET 4 or .loadby sos mscorwks for 2 or 3.5.

After letting the application run for a while, pause it (break all). Now you can load SOS. Upon success, enter !dumpheap -stat. This will list off how much memory each class is using. If this isn't enough to find the leak, the other article I linked goes into more depth on how to locate the memory leak.

Timiz0r
  • 1,304
  • 7
  • 7
  • Actually, I guess I read the graph wrong, so you probably don't have one (unless I'm reading it wrong again D:). I guess I could leave it up here just in case it comes in handy for other peoples' memory problems. – Timiz0r Mar 24 '12 at 00:30
0

One way to solve this is break up your work into separate executable programs. Once a program completes its work and ends, all its memory will be reclaimed by the system.

ahazzah
  • 756
  • 1
  • 7
  • 18