memory&handles growth due to not disposing command?

  • Thread starter Thread starter greatbrendi
  • Start date Start date
G

greatbrendi

Hi,

It seems that when I don't call command.dispose of SQLClient provider
my memory & Handle count of my exe process is growing non-stop, till
there are no resources left on the computer.
I use .NET framework 1.1.

when I call the command.dispose it seems that after a while the GC
collects what it supposed to.

Is anyone familiar with this phenomenon?


thanks ahead!
 
Is there anything else in your application which might be causing this?
What sort of a command are you using? Have you installed the latest Service
Pack for your framework?

-Altaf [MVP]
 
Greatbrendi,

Your question is asked at least 2 times a week in one of these
dotnet.newsgroups. (Which does not mean that you should not ask it, however
to give you an idea how much there is written about this).

Probably you are checking it in the taskmanager which is not accurate for
this.

The dispose does *not* release memory. It is a signal to the GC that it can
be checked to release it.

Objects are released when they have no any reference anymore or that there
is nothing for itself from a not to release object referencing anymore to
it, which is of course a quiet difficult operation and done by the GC.

If you want to know more at memorymanagement, have than a look what Willy
wrote in the newsgroup dotnet.general about it.

http://groups.google.com/group/micr...kmanager&qt_g=1&searchnow=Search+this+groupHe wrote much more than this about this subject, however if you want to knowmore, do than some searches yourself.As well interesting is this new article.http://msdn2.microsoft.com/en-us/library/aax125c9I hope this helps,Cor
 
Why don't you call Dispose since SqlCommand implements IDisposable?
This phenomenom is called "I don't call Dispose for whatever reason but I
should call it".
Anyway, command SqlCommand class normally doesn't use unmanaged resources.
 
Miha,

I have thought a little bit of that disposing question of the connection.
(AFAIK is this is not earlier written in this newsgroup) so I am ready for a
discussion with guys as you.

I think that it is good to use the "close" of a connection at by instance by
the designer created connection.

The advance is that by the designer is created a global "new" connection
object and therefore you have only to open and to close it, while otherwise
you will have to create every time over the already global existing object
address placeholder a new object. Every disposing even if you doubt is done
by the by the form or component automaticly created Idisposable
implementation in that class.

If you do it by hand and you don't set the connection object globaly (The
last I never do), than using dispose instead of the close gives the
behaviour as you told. If you than have the slightest idea that it will not
be disposed, than that does not harm very much (it removes the connection
strings in advance that it is collected by the GC and gives the GC the sign
that it is ready to collect.

Although I have not the idea that this will improve much, because as I
thought that I have read here from Bill Vaughn and X does is the close
already remove the connection from the pool (If somebody as Bill or Marina
or somebody else who has tested this cofirm or deny this behaviour. If not
than I will test this once in future).

If you use the connection object by hand globaly, than it has in my idea not
much sence to dispose, I have not readed that it will be set to nothing by
the dispose and therefore it keeps its reference. Therefore it will keeps
its reference and only be released by the GC if a new object is created
using that placeholder for that address or the program finishes.

Shoot

:-))

Cor

PS. X is a Microsoft guy with a for me Spanish sounding name, however it
seems that my brain has with those names a problem to remember them. As with
most names however with those especially (except Angel).
 
Cor,

Cor Ligthert said:
Miha,

I have thought a little bit of that disposing question of the connection.
(AFAIK is this is not earlier written in this newsgroup) so I am ready for
a discussion with guys as you.

I think that it is good to use the "close" of a connection at by instance
by the designer created connection.

I thought we were talking about SqlCommand and not SqlConnection in this
thread?
The advance is that by the designer is created a global "new" connection
object and therefore you have only to open and to close it, while
otherwise you will have to create every time over the already global
existing object address placeholder a new object. Every disposing even if
you doubt is done by the by the form or component automaticly created
Idisposable implementation in that class.

Using a global connection is not a very good idea, specially if you are
doing threading.
If you do it by hand and you don't set the connection object globaly (The
last I never do), than using dispose instead of the close gives the
behaviour as you told. If you than have the slightest idea that it will
not be disposed, than that does not harm very much (it removes the
connection strings in advance that it is collected by the GC and gives the
GC the sign that it is ready to collect.

No, Dispose doesn't give any sign to GC. Dispose is used just for disposing
everything used by that instance.
GC will collect the instance at certain point in time regardless of Dispose
being called or not. The only thing that GC watches is reference count on
that instance.
And when talking what Dispose in SqlConnection currently does - it removes
only the reference to the connection string (not sure if we agree on this
point).
Although I have not the idea that this will improve much, because as I
thought that I have read here from Bill Vaughn and X does is the close
already remove the connection from the pool (If somebody as Bill or Marina
or somebody else who has tested this cofirm or deny this behaviour.

Of course it doesn't remove it from the pool just by calling
SqlConnection.Close. Connection is removed from the pool when it is closed
and the pool decides to remove it based on pooling parameters (you can set
how many connections are kept in pool).

If not
than I will test this once in future).

Perhaps it currently doesn't do very much. However are you sure that
SqlConnection.Dispose in .net 2.0 will behave the same? What about v3? Can
you guarantee me that it won't be necessary to call it?
 
Miha,
I thought we were talking about SqlCommand and not SqlConnection in this
thread?

Sorry added it to the wrong thread. However in my opinion is to use the
dispose from the sqlcommand absolute withouth any sence.

It is in my opinion just there because it got it from Icomponent. While you
can of course override it with your own extra's. I did not check if the
sqlcommand is inheritable before you write it, I mean this in general.
Using a global connection is not a very good idea, specially if you are
doing threading.
No but the designer does and a lot of the Microsoft documentation is based
on that, as you would have seen further in my message do I not use it.
No, Dispose doesn't give any sign to GC. Dispose is used just for
disposing everything used by that instance.
GC will collect the instance at certain point in time regardless of
Dispose being called or not. The only thing that GC watches is reference
count on that instance.
And when talking what Dispose in SqlConnection currently does - it removes
only the reference to the connection string (not sure if we agree on this
point).
Almost completly agreed, however in my opinion Dispose should release every
"unmanaged resource". I wrote in my further message about that already that
the only thing that I know that the connection.dispose extra (overridden)
does is removing the real connectionstring added to the object.

Of course it doesn't remove it from the pool just by calling
SqlConnection.Close. Connection is removed from the pool when it is closed
and the pool decides to remove it based on pooling parameters (you can set
how many connections are kept in pool).

A kind of how we both express this, however the close starts this as far as
I know.
(In witch I am everytime confused because what is written about that in this
newsgroup)
Perhaps it currently doesn't do very much. However are you sure that
SqlConnection.Dispose in .net 2.0 will behave the same? What about v3? Can
you guarantee me that it won't be necessary to call it?
--

This can in my opinion never be an argument, than you should forever with
every method have to think if this will not happen in future.

This has to do with backwards compatibility. As long as Microsoft does not
have written for any language for Net. "You *should* forever use dispose if
that method is in a class" than it is completely their problem. I have never
seen this in any official Microsoft documentation. If you can point me on
that (official not a kind of blog or article), than I will gladly see that.

As we have seen with VB6 Microsoft has made very much documentation how to
overcome not resolved backward compatibility problems and even created a
VisualBasic compatible namespace for that (not to confuse with the Visual
basic namespace). In version 2005 this from VB6 to VB2005 will even be
improved.

If you probably already have seen are by instance things as the
parametercollection.add in some cases changed to
parametercollection.addwithvalue. At least in VBNet are you warned for the
change if you use that kind of code.

All just my opinion of course.

:-)

Cor
 
Cor,

Almost completly agreed, however in my opinion Dispose should release
every "unmanaged resource".

This is the primary function of Dispose. However, Dispose is also used to
release managed resources when it is not called from within GC.
This can in my opinion never be an argument, than you should forever with
every method have to think if this will not happen in future.

LOL. Cor, some people build applications that will run in next .net version,
too.
This has to do with backwards compatibility.

No, it doesn't. See below what docs say about SqlConnection.Dispose.

As long as Microsoft does not
have written for any language for Net. "You *should* forever use dispose
if that method is in a class" than it is completely their problem. I have
never seen this in any official Microsoft documentation. If you can point
me on that (official not a kind of blog or article), than I will gladly
see that.

Straight from .net help files of SqlConnection.Dispose:
"Releases the unmanaged resources used by the SqlConnection and optionally
releases the managed resources."
Can't be clearer that that...

What about other classes, perhaps non MS - ones with no documentation or
poor documentation or wrong documentation or documentation change in next
version?
Go ahead, do blindly trust documentation and your app will behave strangely
in future or at present time.
IDisposable is a contract. If you don't call Dispose then it is your problem
regardless to the documentation.
 
Miha,
This is the primary function of Dispose. However, Dispose is also used to
release managed resources when it is not called from within GC.
Are you sure that you are *not* talking about the protected overloaded
dispose(boolean) method.

This is written in the new documentation about the public one

Call Dispose when you are finished using the Component. The Dispose method
leaves the Component in an unusable state. After calling Dispose, you must
release all references to the Component so the garbage collector can reclaim
the memory that the Component was occupying. For more information, see
Cleaning Up Unmanaged Resources and Implementing a Dispose Method.
Straight from .net help files of SqlConnection.Dispose:
"Releases the unmanaged resources used by the SqlConnection and optionally
releases the managed resources."
Can't be clearer that that...

In my idea is this as I wrote above already in the old documentation and
than the *optionally* is about the protected overloaded dispose(boolean)

I think that the rest as answer on your addition is written as well with
this.

Don't think that I want to teach you or something like that, I want to have
it more clear for myself as well, to have not any doubts.

Cor
 
Cor,

Cor Ligthert said:
Miha,

Are you sure that you are *not* talking about the protected overloaded
dispose(boolean) method.

This is written in the new documentation about the public one

Call Dispose when you are finished using the Component. The Dispose method
leaves the Component in an unusable state. After calling Dispose, you must
release all references to the Component so the garbage collector can
reclaim the memory that the Component was occupying. For more information,
see Cleaning Up Unmanaged Resources and Implementing a Dispose Method.

And you were saying that nowhere is stated than one should call Dispose and
suggesting people not to call it and saying that MS should provide backward
compatibility if programmers don't call Dispose?
In my idea is this as I wrote above already in the old documentation and
than the *optionally* is about the protected overloaded dispose(boolean)

Cor, you are missing some key details on Dispose mechanism. The public
Dispose should call protected virtual Dispose(bool) internally and this is
how it is done in Component.
The same documentation is valid for both overloads - even documentation is
clear on this topic, well, almost clear.
I think that the rest as answer on your addition is written as well with
this.

Don't think that I want to teach you or something like that, I want to
have it more clear for myself as well, to have not any doubts.

Personally, I would't recommend ignoring Dispose if I don't have the facts
straight.
 
well, I've started this session, and it seems that I was wrong and that
the dispose of command was not my problem.
now, when I call it I still get non-stop Handles & Memory growth
problem.
I collected some performance counter information , but I'm not quite
positive of its analysis.
I will (very) appriciate help.
so,
It seems that the %Time in GC is equal or less than 10%. I understand
this is indicates the the GC is not working too hard.
I have a growing GC Handles which is just like the growing of the
process' handles.
I don't have Promoted bytes at all
and GEN1 is the only GEN which grows.
how can I use this to find the leak?
how do I find my GEN1 objects... I have to find it in my code since I
cannot reconstruct the problem.

thanks!
 
well, I've started this session, and it seems that I was wrong and that
the dispose of command was not my problem.

This doesn't surprise me at all.
You should take a look at a memory profiler, for example at AQTime from
www.automatedqa.com.
Or any similar product - there are also free ones.
 
Back
Top