Garbage Collection

G

Guest

Hi,

I have a windows app that i'm using to transfer images from one SQL DB to
another doing some processing inbetween because the DB table structures to
hold the images are different.

What i'm finding is that the process fails after several hundred images with
an Out Of Memory Exception. I can see from Task Manager that my app is
chewing up memory (over 1GB) just before I get this error. I've have double
checked all my code and i'm closing all DB connections and memory streams etc
so in theory there should be no memory leaks. It just seems that the garbage
collector is not being called, even when I make an explicit call to
GC.Collect it doesn't seem to get called...

Any ideas?
 
J

Jean-Paul Mars via DotNetMonster.com

As far as I understand the .net framework, one cannot explicitly call for
the GC.

(Nu such thing as manually calling a destructor as you could in c++)

Next is in VB.NET, quite sure it's quite the same in C#

You can, however, implement "IDisposable".
Further, when you're running into memory problems, try to set variables to
"nothing", so the GC may collect them as soon as possible.

What I dont understand is why you're talking anout "all DB connections":
you said you
- read stuff from database A,
- do some rewriting,
- store them in database B.

I dont see why there is a need for more than two open connections at any
given time.
 
G

Guest

Hi Paul,

My understanding is calling GC.Collect will force the garbage collector to
be called. At all other times your right the GC is non-deterministic but
should awake when memory is low, my problem is that this doesn't seem to
happen.

I'm not using any custom objects to dispose of but I am maintaining some DB
connections and also some streams. I just wanted to point out that I am
closing the streams and DB connections at the correct times and therefore
unmanaged resources should not be held on to for any longer than necessary.
 
J

Jean-Paul Mars via DotNetMonster.com

True, but System.GC.Collect() should not be used lighthearded: Usually the
GC quite well knows what it's doing, althoug in your case apparently not ;)


But I wonder wonder why your app is eating up memory. If I understand what
your program does is basicly:

Open connection to database_1
Open connection to database_2

read first row (including picture) from database_1 to memory
do some calculation
write first row (including picture) from memory to database_2

read second row (including picture) from database_1 to memory
do some calculation
write second row (including picture) from memory to database_2

....

read last row (including picture) from database_1 to memory
do some calculation
write last row (including picture) from memory to database_2

close connection to database_1
close connection to database_2

If that is the case, you can constantly re-use variables used in the while
(or whatever) loop, and you should not ever reach a 1GB memory usage
(unless you are storing 1GB pictures in your DB, that is).

Or am I missing something?
 
J

Jon Skeet [C# MVP]

Further, when you're running into memory problems, try to set variables to
"nothing", so the GC may collect them as soon as possible.

That's rarely a good idea. The GC can spot local variables which can't
be used again in a method, and most member variables should last as
long as their containing object.

It's very rare to find a situation where setting the variable's value
to Nothing/null helps.
 
A

Anubhav Mishra

you can explicitly called .Collect of GC passing the generation number that
the GC should collect, you should also check at the SQL Server end for the
number of open connections, I hope u are closing the connection and not
waiting for the GC to clear it up.
THanks
Anubhav
 
D

David Levine

That's rarely a good idea. The GC can spot local variables which can't
be used again in a method, and most member variables should last as
long as their containing object.

It's very rare to find a situation where setting the variable's value
to Nothing/null helps.


That is correct when the variable's lifetime is scoped to a method. If the
variable's reference is stored a field in a containing object then it is
useful to set the variable to null because the containing object itself may
still be reachable.
 
J

Jon Skeet [C# MVP]

David Levine said:
That is correct when the variable's lifetime is scoped to a method. If the
variable's reference is stored a field in a containing object then it is
useful to set the variable to null because the containing object itself may
still be reachable.

It's only helpful if the containing object is likely to still be useful
after the member variable is. I usually find that if that's the case,
there's a problem with the design of the object in the first place. I
only rarely find that I want half an object to still be valid.
 
D

David Levine

That is correct when the variable's lifetime is scoped to a method. If
It's only helpful if the containing object is likely to still be useful
after the member variable is. I usually find that if that's the case,
there's a problem with the design of the object in the first place. I
only rarely find that I want half an object to still be valid.

It is rare but occasionally it comes up. For example, when deserializing an
object that implements ISerializable you might need to save the
serialization stream in the object for the use of the deserialization
complete callback. When the callback is done you should null the field so it
can be GCd. I only mentioned it as a minor point.
 
J

Jon Skeet [C# MVP]

David Levine said:
It is rare but occasionally it comes up.

Absolutely. Hence the comment in my original post that it was very
rarely useful.
For example, when deserializing an
object that implements ISerializable you might need to save the
serialization stream in the object for the use of the deserialization
complete callback. When the callback is done you should null the field so it
can be GCd. I only mentioned it as a minor point.

Right - it's the kind of situation I try to avoid where at all possible
though :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top