Big memory usage, GC don''t collect.

Hi!

I'm writing a multithreading app that retreive data entities from the data base very quickly.

In the GetEntity method, i read a IDataReader an create a new data Entity for each register, when it runs for a while (8000 entities retrieved) the memory usage is over 1Gb!! When a entity is created, is throwed in a event, processed and forgoted.

I think that happens because i generate reference objects (the entities) very quickly, the memory is exahusted. I need free this forgoted entities after process it.

In the NewEntity event handler, i count how many entities has arrived, each 1000 entities i call:

GC.Collect(0);
GC.Collect(1);
GC.Collect(2);
GC.WaitingForPendingFinalizers();

But the memory don't reduce its usage.

What can i do ?

Thanks in advance.

Regards.

[1040 byte] By [vtortola] at [2008-1-9]
# 1

How are you checking your memory usage?

MattiasSj?gren at 2007-10-3 > top of Msdn Tech,.NET Development,Common Language Runtime...
# 2
From ProcessExplorer (Sysinternals).

In several minutes i get a OutOfMemoryException.

Regards.

vtortola at 2007-10-3 > top of Msdn Tech,.NET Development,Common Language Runtime...
# 3

The experts says GC.Collect(0); is not good for either C# or VB, the IDataReader implements IDisposable so you can wrap your reader with the second Using statement which can call Dispose for you automatically. That said I think you need to model your objects and the relational layer of you application so your 8000 entities can be reduced much smaller size. You can use stored procedures, Views, split tables and temp table to bring back only what you need per connection. The link below covers the dispose pattern but that will not fix what I see as design related problems. Hope this helps.


http://blogs.msdn.com/andrewdownum/archive/2005/01/04/346448.aspx

Caddre at 2007-10-3 > top of Msdn Tech,.NET Development,Common Language Runtime...
# 4
Caddre wrote:

The experts says GC.Collect(0); is not good for either C# or VB, the IDataReader implements IDisposable so you can wrap your reader with the second Using statement which can call Dispose for you automatically. That said I think you need to model your objects and the relational layer of you application so your 8000 entities can be reduced much smaller size. You can use stored procedures, Views, split tables and temp table to bring back only what you need per connection. The link below covers the dispose pattern but that will not fix what I see as design related problems. Hope this helps.


http://blogs.msdn.com/andrewdownum/archive/2005/01/04/346448.aspx

I'm using IDisposable pattern yet, the entities can't be reduced because we need all properties and we need obtain this >8000 entities to save it in a XML file Stick out tongue The entities could be IDisposable too, but don't matters because all fields are strings (refence objects that must be collected).

For it, in don't understand that the GC can't collect this unreferenced objects (forgoted entities). The memory leak problem is in this big amount of unreferenced objects in the heap. In fact, i get a OutOfMemoryException in not many minutes.

Regards.

vtortola at 2007-10-3 > top of Msdn Tech,.NET Development,Common Language Runtime...
# 5
XML serialization is prone to cause dangling object references. Check this article for reference.
nobugz at 2007-10-3 > top of Msdn Tech,.NET Development,Common Language Runtime...
# 6

(don't matters because all fields are strings (refence objects that must be collected).)

Strings are immutable so I don't think that is relevant and you can use XQuery to reduce the items in memory so I still think this is design related problem that is showing up as a performance issue.

Caddre at 2007-10-3 > top of Msdn Tech,.NET Development,Common Language Runtime...
# 7
Hi all !!

nobugz wrote:
XML serialization is prone to cause dangling object references. Check this article for reference.

At this moment i'm omiting this part, the event is handled, the entity count and forgeted. Build a XML is the next stage.

Caddre wrote:

(don't matters because all fields are strings (refence objects that must be collected).)

Strings are immutable so I don't think that is relevant and you can use XQuery to reduce the items in memory so I still think this is design related problem that is showing up as a performance issue.

I'm tested that if i retrieve the data from the BD but i don't create a entity for each registry... memory leak doesn't happen.

The memory usage grows directly proportional to the entities retrieval.

However, the problem is that i can't force GC to collect this unused entities. Tomorrow i will try with the CLR Profiler to ensure that really this entities are sucking my memory.

Regards.

vtortola at 2007-10-3 > top of Msdn Tech,.NET Development,Common Language Runtime...

.NET Development

Site Classified