views:

138

answers:

4

Hi,

I have a fewSortedList<>andSortedDictionary<>structures in my simulation code and I add millions of items in them over time. The problem is that the garbage collector does not deallocate quickly enough memory so there is a huge hit on the application's performance. My last option was to engage theGC.Collect()method so that I can reclaim that memory back. Has anyone got a different idea? I am aware of theFlyweightpattern which is another option but I would appreciate other suggestions that would not require huge refactoring of my code.

+2  A: 

I'd start with doing some memory profiling on your application to make sure that the items you remove from those lists (which I assume is happening from the way your post is written) are actually properly released and not hanging around places.

What sort of performance hit are we talking and on what operating system? If I recall, GC will run when it's needed, not immediately or even "soon". So task manager showing high memory allocated to your application is not necessarily a problem. What happens if you put the machine under higher load (e.g. run several copies of your application)? Does memory get reclaimed faster in that scenario or are you starting to run out of memory?

I hope answers to these questions will help point you in a right direction.

Anna Lear
Yes I do indeed clear the data structures and I am talking about the speed that the `GC` collects memory. I have the task manager open and it seems that memory is still allocated for a very long time. I always have to do `Collect` in order to get it back. And the problem is in my simulations even though my machine gets quickly out of memory the GC does nothing. I have a WinXP SP3 configuration.
Dimitris
+1  A: 

Well, if you keep all of the items in those structures, the GC will never collect the resources because they still have references to them.

If you need the items in the structures to be collected, you must remove them from the data structure.

To clear the entire data structure try using Clear() and setting the data structure reference to null. If the data is still not getting collected fast enough, call CC.Collect().

jjnguy
+3  A: 

You are fighting the "There's no free lunch" principle. You cannot assume that stuffing millions of items in a list isn't going to affect perf. Only the SortedList<> should be a problem, it is going to start allocating memory in the Large Object Heap. That allocation isn't going to be freed soon, it takes a gen #2 collection to chuck stuff out of the LOH again. This delay should not otherwise affect the perf of your program.

One thing you can do is avoiding the multiple of copies of the internal array that SortedList<> will jam into the LOH when it keeps growing. Try to guess a good value for Capacity so it pre-allocates the large array up front.

Next, use Perfmon.exe or TaskMgr.exe and looks at the page fault delta of your program. It should be quite busy while you're allocating. If you see low values (100 or less) then you might have a problem with the paging file being fragmented. A common scourge on older machines that run XP. Defragging the disk and using SysInternals' PageDefrag utility can do extraordinary wonders.

Hans Passant
Actually `Capacity` is one property I haven't played around with much, worth pointing out. For the time being I am calling `GC.Collect` on every iteration of my simulation loop. Wish I could just defrag my disk but this is an app used by a few people.
Dimitris
A: 

I think the SortedList uses a array as backing field, which means that large SortedList get allocated on the Large object heap. The large object heap can get defragmentated, which can cause an out of memory exception while in principle there is still enough memory available. See this link. This might be your problem, as intermediate calls to GC.collect prevent the LOH from getting badly defragmented in some scenarios, which explains why calling it helps you reduce the problem.

The problem can be mitigated by splitting large objects into smaller fragments.

willem