473,399 Members | 3,106 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,399 software developers and data experts.

reference not removed revisited

Hello,
I again ask for help on the next problem, a previous question did not give a
solution.

The method at the bottom of this message leaves a reference to somethig, as
far as I can tell to the _sqladapter variable. As you can see I use the
'using' statement so the adapter and the connection should be neatly
disposed of.
But it doesn't!
I will be praying for a solution.
Thanks
Frank
public DataTable lees()
{
string ConnectString="Server= localhost; database=aa; User
id=uniserver;password=aa;Connect Timeout=100;";
DataSet _DataSet= new DataSet();
string StoredProcedure="S_aa";
using (SqlConnection _SqlConnection= new SqlConnection(ConnectString))
{
using (SqlDataAdapter _SqlDataAdapter = new
SqlDataAdapter(StoredProcedure,_SqlConnection))
{
try
{
_SqlDataAdapter.SelectCommand.CommandType=CommandT ype.StoredProcedure;
_SqlDataAdapter.Fill(_DataSet,StoredProcedure);
_SqlDataAdapter.SelectCommand=null;
}
catch (SqlException e)
{
Console.WriteLine(StoredProcedure+e.Message+e.Stac kTrace);
}
}
}
return _DataSet.Tables[0];
}
Nov 17 '05 #1
22 1357
HI,

How do you know it?

Also remember that the GC is not deterministic, all you can assure is that
the Dispose method will be called ( cause of the using )

Now, do this. inherit from SqlDataAdapter and override Dispose , then you
will see when it's called.
IIRC Dispose call Close , so if it's called as expected the connection is
closed and the objects are ready to be GC.

Cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation

"Frank" <fr***@frank.com> wrote in message
news:42***********************@news.xs4all.nl...
Hello,
I again ask for help on the next problem, a previous question did not give
a solution.

The method at the bottom of this message leaves a reference to somethig,
as far as I can tell to the _sqladapter variable. As you can see I use the
'using' statement so the adapter and the connection should be neatly
disposed of.
But it doesn't!
I will be praying for a solution.
Thanks
Frank
public DataTable lees()
{
string ConnectString="Server= localhost; database=aa; User
id=uniserver;password=aa;Connect Timeout=100;";
DataSet _DataSet= new DataSet();
string StoredProcedure="S_aa";
using (SqlConnection _SqlConnection= new SqlConnection(ConnectString))
{
using (SqlDataAdapter _SqlDataAdapter = new
SqlDataAdapter(StoredProcedure,_SqlConnection))
{
try
{

_SqlDataAdapter.SelectCommand.CommandType=CommandT ype.StoredProcedure;
_SqlDataAdapter.Fill(_DataSet,StoredProcedure);
_SqlDataAdapter.SelectCommand=null;
}
catch (SqlException e)
{
Console.WriteLine(StoredProcedure+e.Message+e.Stac kTrace);
}
}
}
return _DataSet.Tables[0];
}

Nov 17 '05 #2
Ignacio,

I use http://www.scitech.se/memprofiler/Default.htm to see the refs. It's a
weakreference.
I'll try your suggestion with the inherit.
Frank
"Ignacio Machin ( .NET/ C# MVP )" <ignacio.machin AT dot.state.fl.us>
schreef in bericht news:ud**************@TK2MSFTNGP14.phx.gbl...
HI,

How do you know it?

Also remember that the GC is not deterministic, all you can assure is that
the Dispose method will be called ( cause of the using )

Now, do this. inherit from SqlDataAdapter and override Dispose , then you
will see when it's called.
IIRC Dispose call Close , so if it's called as expected the connection is
closed and the objects are ready to be GC.

Cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation

"Frank" <fr***@frank.com> wrote in message
news:42***********************@news.xs4all.nl...
Hello,
I again ask for help on the next problem, a previous question did not
give a solution.

The method at the bottom of this message leaves a reference to somethig,
as far as I can tell to the _sqladapter variable. As you can see I use
the 'using' statement so the adapter and the connection should be neatly
disposed of.
But it doesn't!
I will be praying for a solution.
Thanks
Frank
public DataTable lees()
{
string ConnectString="Server= localhost; database=aa; User
id=uniserver;password=aa;Connect Timeout=100;";
DataSet _DataSet= new DataSet();
string StoredProcedure="S_aa";
using (SqlConnection _SqlConnection= new SqlConnection(ConnectString))
{
using (SqlDataAdapter _SqlDataAdapter = new
SqlDataAdapter(StoredProcedure,_SqlConnection))
{
try
{

_SqlDataAdapter.SelectCommand.CommandType=CommandT ype.StoredProcedure;
_SqlDataAdapter.Fill(_DataSet,StoredProcedure);
_SqlDataAdapter.SelectCommand=null;
}
catch (SqlException e)
{
Console.WriteLine(StoredProcedure+e.Message+e.Stac kTrace);
}
}
}
return _DataSet.Tables[0];
}


Nov 17 '05 #3
Ignacio,
I tried the inherit but I get an error at 'public class
newclass:SqlDataAdapter'.
Do I have to do that in another way?
Regards
Frank
"Ignacio Machin ( .NET/ C# MVP )" <ignacio.machin AT dot.state.fl.us>
schreef in bericht news:ud**************@TK2MSFTNGP14.phx.gbl...
HI,

How do you know it?

Also remember that the GC is not deterministic, all you can assure is that
the Dispose method will be called ( cause of the using )

Now, do this. inherit from SqlDataAdapter and override Dispose , then you
will see when it's called.
IIRC Dispose call Close , so if it's called as expected the connection is
closed and the objects are ready to be GC.

Cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation

"Frank" <fr***@frank.com> wrote in message
news:42***********************@news.xs4all.nl...
Hello,
I again ask for help on the next problem, a previous question did not
give a solution.

The method at the bottom of this message leaves a reference to somethig,
as far as I can tell to the _sqladapter variable. As you can see I use
the 'using' statement so the adapter and the connection should be neatly
disposed of.
But it doesn't!
I will be praying for a solution.
Thanks
Frank
public DataTable lees()
{
string ConnectString="Server= localhost; database=aa; User
id=uniserver;password=aa;Connect Timeout=100;";
DataSet _DataSet= new DataSet();
string StoredProcedure="S_aa";
using (SqlConnection _SqlConnection= new SqlConnection(ConnectString))
{
using (SqlDataAdapter _SqlDataAdapter = new
SqlDataAdapter(StoredProcedure,_SqlConnection))
{
try
{

_SqlDataAdapter.SelectCommand.CommandType=CommandT ype.StoredProcedure;
_SqlDataAdapter.Fill(_DataSet,StoredProcedure);
_SqlDataAdapter.SelectCommand=null;
}
catch (SqlException e)
{
Console.WriteLine(StoredProcedure+e.Message+e.Stac kTrace);
}
}
}
return _DataSet.Tables[0];
}


Nov 17 '05 #4
Frank wrote:

[...snip...]
I use http://www.scitech.se/memprofiler/Default.htm to see the refs. It's a weakreference.

[...snip...]

A weak referencs should not prevent the object from being garbage collected,
as long as there is no other strong reference:

http://msdn.microsoft.com/msdnmag/is...2/default.aspx
Nov 17 '05 #5
Hi Frank,
Unfortunally SqlDatAdapter is marked as sealed :(

So what I proposed before cannot be done, sorry for the mistake, I did not
check that SqlDataAdapter was sealed. ( ITOH I do not see why it's sealed in
the first place)
As Voss noted a weakreference can be GC , so what I propose you to do is
give time to the GC to run ( or force it using GC.Collect () ) and see what
happens.
cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation

"Frank" <fr***@frank.com> wrote in message
news:42***********************@news.xs4all.nl...
Ignacio,
I tried the inherit but I get an error at 'public class
newclass:SqlDataAdapter'.
Do I have to do that in another way?
Regards
Frank
"Ignacio Machin ( .NET/ C# MVP )" <ignacio.machin AT dot.state.fl.us>
schreef in bericht news:ud**************@TK2MSFTNGP14.phx.gbl...
HI,

How do you know it?

Also remember that the GC is not deterministic, all you can assure is
that the Dispose method will be called ( cause of the using )

Now, do this. inherit from SqlDataAdapter and override Dispose , then you
will see when it's called.
IIRC Dispose call Close , so if it's called as expected the connection is
closed and the objects are ready to be GC.

Cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation

"Frank" <fr***@frank.com> wrote in message
news:42***********************@news.xs4all.nl...
Hello,
I again ask for help on the next problem, a previous question did not
give a solution.

The method at the bottom of this message leaves a reference to somethig,
as far as I can tell to the _sqladapter variable. As you can see I use
the 'using' statement so the adapter and the connection should be neatly
disposed of.
But it doesn't!
I will be praying for a solution.
Thanks
Frank
public DataTable lees()
{
string ConnectString="Server= localhost; database=aa; User
id=uniserver;password=aa;Connect Timeout=100;";
DataSet _DataSet= new DataSet();
string StoredProcedure="S_aa";
using (SqlConnection _SqlConnection= new SqlConnection(ConnectString))
{
using (SqlDataAdapter _SqlDataAdapter = new
SqlDataAdapter(StoredProcedure,_SqlConnection))
{
try
{

_SqlDataAdapter.SelectCommand.CommandType=CommandT ype.StoredProcedure;
_SqlDataAdapter.Fill(_DataSet,StoredProcedure);
_SqlDataAdapter.SelectCommand=null;
}
catch (SqlException e)
{
Console.WriteLine(StoredProcedure+e.Message+e.Stac kTrace);
}
}
}
return _DataSet.Tables[0];
}



Nov 17 '05 #6

"Frank" <fr***@frank.com> wrote in message
news:42***********************@news.xs4all.nl...
Hello,
I again ask for help on the next problem, a previous question did not give
a solution.

The method at the bottom of this message leaves a reference to somethig,
as far as I can tell to the _sqladapter variable. As you can see I use the
'using' statement so the adapter and the connection should be neatly
disposed of.
But it doesn't!
I will be praying for a solution.
Thanks
Frank
public DataTable lees()
{
string ConnectString="Server= localhost; database=aa; User
id=uniserver;password=aa;Connect Timeout=100;";
DataSet _DataSet= new DataSet();
string StoredProcedure="S_aa";
using (SqlConnection _SqlConnection= new SqlConnection(ConnectString))
{
using (SqlDataAdapter _SqlDataAdapter = new
SqlDataAdapter(StoredProcedure,_SqlConnection))
{
try
{

_SqlDataAdapter.SelectCommand.CommandType=CommandT ype.StoredProcedure;
_SqlDataAdapter.Fill(_DataSet,StoredProcedure);
_SqlDataAdapter.SelectCommand=null;
}
catch (SqlException e)
{
Console.WriteLine(StoredProcedure+e.Message+e.Stac kTrace);
}
}
}
return _DataSet.Tables[0];
}


Both are neatly disposed, that is Dispose is called on both objects at the
end of the using block.
Seems like you are confusing "Disposing" with "object lifetime", when
Dispose is called on a Dataset the underlying memory resources will be
released, when called on a SqlConnection the connection returns to the pool.
The object references (_DataSet, _SqlConnection and _SqlDataAdapter ) are
nulled on return and the objects they refer to become eligible for
collection by the GC, however, this clean-up is non deterministic so it
might take a while before it happens and is depending on your object
allocation scheme.

If you aren't sure about this you can register a Disposed event handler ;-)

using (SqlConnection _SqlConnection = new
SqlConnection(ConnectString))
{
_SqlConnection.Disposed += new EventHandler( OnSQLDisposed);
static void OnSQLDisposed(object sender, EventArgs e)
{
Console.WriteLine("Disposed {0}", sender);
}

Willy.


Nov 17 '05 #7
Hi,
I tried a forced GC: no difference. I tried this program in a loop and after
500.000 instances I have have 500.000 references. It's just not
garbage collected.
Greets
Frank
"Ignacio Machin ( .NET/ C# MVP )" <ignacio.machin AT dot.state.fl.us>
schreef in bericht news:%2****************@TK2MSFTNGP14.phx.gbl...
Hi Frank,
Unfortunally SqlDatAdapter is marked as sealed :(

So what I proposed before cannot be done, sorry for the mistake, I did not
check that SqlDataAdapter was sealed. ( ITOH I do not see why it's sealed
in the first place)
As Voss noted a weakreference can be GC , so what I propose you to do is
give time to the GC to run ( or force it using GC.Collect () ) and see
what happens.
cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation

"Frank" <fr***@frank.com> wrote in message
news:42***********************@news.xs4all.nl...
Ignacio,
I tried the inherit but I get an error at 'public class
newclass:SqlDataAdapter'.
Do I have to do that in another way?
Regards
Frank
"Ignacio Machin ( .NET/ C# MVP )" <ignacio.machin AT dot.state.fl.us>
schreef in bericht news:ud**************@TK2MSFTNGP14.phx.gbl...
HI,

How do you know it?

Also remember that the GC is not deterministic, all you can assure is
that the Dispose method will be called ( cause of the using )

Now, do this. inherit from SqlDataAdapter and override Dispose , then
you will see when it's called.
IIRC Dispose call Close , so if it's called as expected the connection
is closed and the objects are ready to be GC.

Cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation

"Frank" <fr***@frank.com> wrote in message
news:42***********************@news.xs4all.nl...
Hello,
I again ask for help on the next problem, a previous question did not
give a solution.

The method at the bottom of this message leaves a reference to
somethig, as far as I can tell to the _sqladapter variable. As you can
see I use the 'using' statement so the adapter and the connection
should be neatly disposed of.
But it doesn't!
I will be praying for a solution.
Thanks
Frank
public DataTable lees()
{
string ConnectString="Server= localhost; database=aa; User
id=uniserver;password=aa;Connect Timeout=100;";
DataSet _DataSet= new DataSet();
string StoredProcedure="S_aa";
using (SqlConnection _SqlConnection= new
SqlConnection(ConnectString))
{
using (SqlDataAdapter _SqlDataAdapter = new
SqlDataAdapter(StoredProcedure,_SqlConnection))
{
try
{

_SqlDataAdapter.SelectCommand.CommandType=CommandT ype.StoredProcedure;
_SqlDataAdapter.Fill(_DataSet,StoredProcedure);
_SqlDataAdapter.SelectCommand=null;
}
catch (SqlException e)
{
Console.WriteLine(StoredProcedure+e.Message+e.Stac kTrace);
}
}
}
return _DataSet.Tables[0];
}



Nov 17 '05 #8

"Frank" <fr***@frank.com> wrote in message
news:d6**********@news5.zwoll1.ov.home.nl...
Hi,
I tried a forced GC: no difference. I tried this program in a loop and
after 500.000 instances I have have 500.000 references. It's just not
garbage collected.
Greets
Frank


Reference to what object and what kind of references (hard/weak)? If you
have 500000 life references your workingset would be high (size depends on
the object). Note also that weakreferences don't stop the GC to collect the
objects refered by.

It also doesn't make sense to call GC.Collect, the GC knows better than you
do when it should run.

Did you try to add this to your code...
using (SqlConnection _SqlConnection = new
SqlConnection(ConnectString))
{
_SqlConnection.Disposed += new EventHandler( OnSQLDisposed);
..

static void OnSQLDisposed(object sender, EventArgs e)
{
Console.WriteLine("Disposed {0}", sender);
}

You will see that Dispose is called.

Another thing I would like to see is your complete code.

Willy.
Nov 17 '05 #9
Willy,
they are weak references, as far as I can tell to the sqladapter.
This is the whole code, I call this method from the main in a
consoleapplication in a loop.
I can see the references with a tool:
http://www.scitech.se/memprofiler/Default.htm
Regards
Frank
"Willy Denoyette [MVP]" <wi*************@telenet.be> schreef in bericht
news:Ob****************@TK2MSFTNGP09.phx.gbl...

"Frank" <fr***@frank.com> wrote in message
news:d6**********@news5.zwoll1.ov.home.nl...
Hi,
I tried a forced GC: no difference. I tried this program in a loop and
after 500.000 instances I have have 500.000 references. It's just not
garbage collected.
Greets
Frank


Reference to what object and what kind of references (hard/weak)? If you
have 500000 life references your workingset would be high (size depends on
the object). Note also that weakreferences don't stop the GC to collect
the objects refered by.

It also doesn't make sense to call GC.Collect, the GC knows better than
you do when it should run.

Did you try to add this to your code...
using (SqlConnection _SqlConnection = new
SqlConnection(ConnectString))
{
_SqlConnection.Disposed += new EventHandler( OnSQLDisposed);
..

static void OnSQLDisposed(object sender, EventArgs e)
{
Console.WriteLine("Disposed {0}", sender);
}

You will see that Dispose is called.

Another thing I would like to see is your complete code.

Willy.

Nov 17 '05 #10

"Frank" <fr***@frank.com> wrote in message
news:d6**********@news4.zwoll1.ov.home.nl...
Willy,
they are weak references, as far as I can tell to the sqladapter.
This is the whole code, I call this method from the main in a
consoleapplication in a loop.
I can see the references with a tool:
http://www.scitech.se/memprofiler/Default.htm
Regards
Frank


I didn't use this tool when I ran your code executing a simple stored
procedure, instead I attached the process to windbg (native debugger) and
used sos.dll to watch the CLR internals.

Here is what I have noticed/measure (your mileage may vary !!) ...

The code iterates 1000 times per second, that means:
-1000 SqlConnection, 1000 DataSet, 1000 SqlDataAdapter and 1000 DataTable
objects created per second, and 1000 SqlConnection and SqlDataAdapter
Disposed.
- each loop returns a DataTable, so 1000 DataTables are returned per sec.
- The GC runs ~40 times per second to collect Gen0, ~1 time/second to
collect Gen0 & Gen1, one or two times during the complete run (500 secs) to
collect Gen2 (full collect).
The number of surviving WeakReferences that reach into Gen2 is about 50 per
second. (16 bytes/WeakReference).
When the GC does a full collect all WeakReferences are removed from the
heap.

Conclusion:
The maximum number of WeakReferences per run was not higher than ~25000
(400000 bytes), and they are removed as expected when the GC does a full
collect.
Seems like the memprofiler is so intruding that he disturbs normal GC run.
So I would say - nothing to worry about.

Willy.




Nov 17 '05 #11
This is helpfull Willy, thank you very much.
I'll contact scitech about this.
Greets
Frank
"Willy Denoyette [MVP]" <wi*************@telenet.be> schreef in bericht
news:%2***************@tk2msftngp13.phx.gbl...

"Frank" <fr***@frank.com> wrote in message
news:d6**********@news4.zwoll1.ov.home.nl...
Willy,
they are weak references, as far as I can tell to the sqladapter.
This is the whole code, I call this method from the main in a
consoleapplication in a loop.
I can see the references with a tool:
http://www.scitech.se/memprofiler/Default.htm
Regards
Frank


I didn't use this tool when I ran your code executing a simple stored
procedure, instead I attached the process to windbg (native debugger) and
used sos.dll to watch the CLR internals.

Here is what I have noticed/measure (your mileage may vary !!) ...

The code iterates 1000 times per second, that means:
-1000 SqlConnection, 1000 DataSet, 1000 SqlDataAdapter and 1000 DataTable
objects created per second, and 1000 SqlConnection and SqlDataAdapter
Disposed.
- each loop returns a DataTable, so 1000 DataTables are returned per sec.
- The GC runs ~40 times per second to collect Gen0, ~1 time/second to
collect Gen0 & Gen1, one or two times during the complete run (500 secs)
to collect Gen2 (full collect).
The number of surviving WeakReferences that reach into Gen2 is about 50
per second. (16 bytes/WeakReference).
When the GC does a full collect all WeakReferences are removed from the
heap.

Conclusion:
The maximum number of WeakReferences per run was not higher than ~25000
(400000 bytes), and they are removed as expected when the GC does a full
collect.
Seems like the memprofiler is so intruding that he disturbs normal GC run.
So I would say - nothing to worry about.

Willy.



Nov 17 '05 #12
I'm not confusing them. In the program I use to see references to objects it
says 'live instances' to sqlAdapter.

"Willy Denoyette [MVP]" <wi*************@telenet.be> schreef in bericht
news:ep**************@tk2msftngp13.phx.gbl...

"Frank" <fr***@frank.com> wrote in message
news:42***********************@news.xs4all.nl...
Hello,
I again ask for help on the next problem, a previous question did not
give a solution.

The method at the bottom of this message leaves a reference to somethig,
as far as I can tell to the _sqladapter variable. As you can see I use
the 'using' statement so the adapter and the connection should be neatly
disposed of.
But it doesn't!
I will be praying for a solution.
Thanks
Frank
public DataTable lees()
{
string ConnectString="Server= localhost; database=aa; User
id=uniserver;password=aa;Connect Timeout=100;";
DataSet _DataSet= new DataSet();
string StoredProcedure="S_aa";
using (SqlConnection _SqlConnection= new SqlConnection(ConnectString))
{
using (SqlDataAdapter _SqlDataAdapter = new
SqlDataAdapter(StoredProcedure,_SqlConnection))
{
try
{

_SqlDataAdapter.SelectCommand.CommandType=CommandT ype.StoredProcedure;
_SqlDataAdapter.Fill(_DataSet,StoredProcedure);
_SqlDataAdapter.SelectCommand=null;
}
catch (SqlException e)
{
Console.WriteLine(StoredProcedure+e.Message+e.Stac kTrace);
}
}
}
return _DataSet.Tables[0];
}


Both are neatly disposed, that is Dispose is called on both objects at the
end of the using block.
Seems like you are confusing "Disposing" with "object lifetime", when
Dispose is called on a Dataset the underlying memory resources will be
released, when called on a SqlConnection the connection returns to the
pool.
The object references (_DataSet, _SqlConnection and _SqlDataAdapter ) are
nulled on return and the objects they refer to become eligible for
collection by the GC, however, this clean-up is non deterministic so it
might take a while before it happens and is depending on your object
allocation scheme.

If you aren't sure about this you can register a Disposed event handler
;-)

using (SqlConnection _SqlConnection = new
SqlConnection(ConnectString))
{
_SqlConnection.Disposed += new EventHandler( OnSQLDisposed);
static void OnSQLDisposed(object sender, EventArgs e)
{
Console.WriteLine("Disposed {0}", sender);
}

Willy.


Nov 17 '05 #13

"Frank" <fr***@frank.com> wrote in message
news:d6**********@news2.zwoll1.ov.home.nl...
I'm not confusing them. In the program I use to see references to objects
it says 'live instances' to sqlAdapter.


Sorry, but the point is that
1. _SqlDataAdapter.Dipose is called at the end of the using block.
2. _SqlDataAdapter is nulled at the end of the same block, so the object
instance is eligible to be collected by the GC.

That means it will be collected at some point in time, but that point is
non-determnistic, it depends on several factors like the Generation the
object belongs to at the moment the GC runs.
If the object is actually in Gen2, it will only be collected when the GC
does a full collect.

Willy.
Nov 17 '05 #14
I disagree, sqladapter will not be collected because it has live references
to it it says so by my debugprogram.
Frank

"Willy Denoyette [MVP]" <wi*************@telenet.be> schreef in bericht
news:u0**************@TK2MSFTNGP09.phx.gbl...

"Frank" <fr***@frank.com> wrote in message
news:d6**********@news2.zwoll1.ov.home.nl...
I'm not confusing them. In the program I use to see references to objects
it says 'live instances' to sqlAdapter.


Sorry, but the point is that
1. _SqlDataAdapter.Dipose is called at the end of the using block.
2. _SqlDataAdapter is nulled at the end of the same block, so the object
instance is eligible to be collected by the GC.

That means it will be collected at some point in time, but that point is
non-determnistic, it depends on several factors like the Generation the
object belongs to at the moment the GC runs.
If the object is actually in Gen2, it will only be collected when the GC
does a full collect.

Willy.

Nov 17 '05 #15

"Frank" <fr***@frank.com> wrote in message
news:d6**********@news4.zwoll1.ov.home.nl...
I disagree, sqladapter will not be collected because it has live references
to it it says so by my debugprogram.
Frank


The sample you posted has one hard reference which is scoped by the using
block, that means that the reference is nulled when leaving the scope.
On another thread you said they were WeakReferences, I ran the code in a
loop as you did and noticed the WeakReference growth, but I also said they
were collected with a full collect.

It's your right to disagree, but to be sure we are talking about the same
thing here, may I ask you to post a complete sample that illustrates the
issue, also what do you mean with your debugprogram.

Willy.
Nov 17 '05 #16
Willy,
as I posted earlier I use http://www.scitech.se/memprofiler/Default.htm,
it's free (for 15 days) and very easy to use.
It shows the weakreference as 'live instances', meaning they are used and
cannot be collected.
Regards
Frank
"Willy Denoyette [MVP]" <wi*************@telenet.be> schreef in bericht
news:eP**************@TK2MSFTNGP10.phx.gbl...

"Frank" <fr***@frank.com> wrote in message
news:d6**********@news4.zwoll1.ov.home.nl...
I disagree, sqladapter will not be collected because it has live
references to it it says so by my debugprogram.
Frank


The sample you posted has one hard reference which is scoped by the using
block, that means that the reference is nulled when leaving the scope.
On another thread you said they were WeakReferences, I ran the code in a
loop as you did and noticed the WeakReference growth, but I also said they
were collected with a full collect.

It's your right to disagree, but to be sure we are talking about the same
thing here, may I ask you to post a complete sample that illustrates the
issue, also what do you mean with your debugprogram.

Willy.

Nov 17 '05 #17

"Frank" <fr***@frank.com> wrote in message
news:d6**********@news6.zwoll1.ov.home.nl...
Willy,
as I posted earlier I use http://www.scitech.se/memprofiler/Default.htm,
it's free (for 15 days) and very easy to use.
It shows the weakreference as 'live instances', meaning they are used and
cannot be collected.
Regards
Frank

Ran following code (using .NET Framework version 1.1.4322 on XP SP2) through
scitech memory profiler v2.5:
The Database (SQL Server 2000) is located on a separate W2K3 server, over a
100Mb/s switched LAN.

using System;
using System.Data;
using System.Data.SqlClient;
namespace Willys
{
class Tester
{
static void Main()
{
for (int i = 0; i < 500000; i++)
{
DataTable dt = Lees();
if (i % 1000 == 0)
{
Console.WriteLine(i); // show loops done
}
}
Console.ReadLine();
}
static DataTable Lees()
{
string ConnectString="Initial Catalog=Northwind;Data
Source=xxx\\sqlinstance;Integrated Security=SSPI;";
DataSet _DataSet= new DataSet();
string StoredProcedure="Ten Most Expensive Products";
using (SqlConnection _SqlConnection = new
SqlConnection(ConnectString))
{
using (SqlDataAdapter _SqlDataAdapter = new
SqlDataAdapter(StoredProcedure,_SqlConnection))
{
try
{
_SqlDataAdapter.SelectCommand.CommandType=CommandT ype.StoredProcedure;
_SqlDataAdapter.Fill(_DataSet,StoredProcedure);
_SqlDataAdapter.SelectCommand=null;
}
catch (SqlException e)
{
Console.WriteLine(StoredProcedure+e.Message+e.Stac kTrace);
}
}
}
return _DataSet.Tables[0];
}
}
}

This is what I noticed:
the number of Live WeakReferences avarages at 22, very rarely drops to
values like 5 and peaks at 64 (in real-time view). The number of SqlAdapters
varies between 0 and 1 (obviously).
The number of WeakReferences at the end of the run is 3 (two of them are
SqlClient related).

As I said before this is a perfectly normal allocation behavior, if you
observe different results running the same code, you must have a problem
with your set-up.

Willy.


Nov 17 '05 #18
Willy,
I am at a loss, the references are indeed removed as expected. But I assure
you they were not when I started this thread. However, I cannot check my
original program as I have it at work, so I will check it tomorrowmorning
(in the Netherlands we have a day off today).
In the meantine, thanks for your time and feedback.

By the way, what do you think of the scitech tool? I think I will register
for a license at work.

Best regards
Frank
"Willy Denoyette [MVP]" <wi*************@telenet.be> schreef in bericht
news:eY**************@TK2MSFTNGP15.phx.gbl...

"Frank" <fr***@frank.com> wrote in message
news:d6**********@news6.zwoll1.ov.home.nl...
Willy,
as I posted earlier I use http://www.scitech.se/memprofiler/Default.htm,
it's free (for 15 days) and very easy to use.
It shows the weakreference as 'live instances', meaning they are used and
cannot be collected.
Regards
Frank

Ran following code (using .NET Framework version 1.1.4322 on XP SP2)
through scitech memory profiler v2.5:
The Database (SQL Server 2000) is located on a separate W2K3 server, over
a 100Mb/s switched LAN.

using System;
using System.Data;
using System.Data.SqlClient;
namespace Willys
{
class Tester
{
static void Main()
{
for (int i = 0; i < 500000; i++)
{
DataTable dt = Lees();
if (i % 1000 == 0)
{
Console.WriteLine(i); // show loops done
}
}
Console.ReadLine();
}
static DataTable Lees()
{
string ConnectString="Initial Catalog=Northwind;Data
Source=xxx\\sqlinstance;Integrated Security=SSPI;";
DataSet _DataSet= new DataSet();
string StoredProcedure="Ten Most Expensive Products";
using (SqlConnection _SqlConnection = new
SqlConnection(ConnectString))
{
using (SqlDataAdapter _SqlDataAdapter = new
SqlDataAdapter(StoredProcedure,_SqlConnection))
{
try
{

_SqlDataAdapter.SelectCommand.CommandType=CommandT ype.StoredProcedure;
_SqlDataAdapter.Fill(_DataSet,StoredProcedure);
_SqlDataAdapter.SelectCommand=null;
}
catch (SqlException e)
{
Console.WriteLine(StoredProcedure+e.Message+e.Stac kTrace);
}
}
}
return _DataSet.Tables[0];
}
}
}

This is what I noticed:
the number of Live WeakReferences avarages at 22, very rarely drops to
values like 5 and peaks at 64 (in real-time view). The number of
SqlAdapters varies between 0 and 1 (obviously).
The number of WeakReferences at the end of the run is 3 (two of them are
SqlClient related).

As I said before this is a perfectly normal allocation behavior, if you
observe different results running the same code, you must have a problem
with your set-up.

Willy.

Nov 17 '05 #19
Willy,
at last!!!!!!!!!!!! I found it. I use [STAThread] in my main class. Removing
that leaves no live instances to weakreferences and adding it gives lots of
references.
Again, thanks for your help.

But, why does this line have this reaction?

Regards

Frank

"Willy Denoyette [MVP]" <wi*************@telenet.be> schreef in bericht
news:eY**************@TK2MSFTNGP15.phx.gbl...

"Frank" <fr***@frank.com> wrote in message
news:d6**********@news6.zwoll1.ov.home.nl...
Willy,
as I posted earlier I use http://www.scitech.se/memprofiler/Default.htm,
it's free (for 15 days) and very easy to use.
It shows the weakreference as 'live instances', meaning they are used and
cannot be collected.
Regards
Frank

Ran following code (using .NET Framework version 1.1.4322 on XP SP2)
through scitech memory profiler v2.5:
The Database (SQL Server 2000) is located on a separate W2K3 server, over
a 100Mb/s switched LAN.

using System;
using System.Data;
using System.Data.SqlClient;
namespace Willys
{
class Tester
{
static void Main()
{
for (int i = 0; i < 500000; i++)
{
DataTable dt = Lees();
if (i % 1000 == 0)
{
Console.WriteLine(i); // show loops done
}
}
Console.ReadLine();
}
static DataTable Lees()
{
string ConnectString="Initial Catalog=Northwind;Data
Source=xxx\\sqlinstance;Integrated Security=SSPI;";
DataSet _DataSet= new DataSet();
string StoredProcedure="Ten Most Expensive Products";
using (SqlConnection _SqlConnection = new
SqlConnection(ConnectString))
{
using (SqlDataAdapter _SqlDataAdapter = new
SqlDataAdapter(StoredProcedure,_SqlConnection))
{
try
{

_SqlDataAdapter.SelectCommand.CommandType=CommandT ype.StoredProcedure;
_SqlDataAdapter.Fill(_DataSet,StoredProcedure);
_SqlDataAdapter.SelectCommand=null;
}
catch (SqlException e)
{
Console.WriteLine(StoredProcedure+e.Message+e.Stac kTrace);
}
}
}
return _DataSet.Tables[0];
}
}
}

This is what I noticed:
the number of Live WeakReferences avarages at 22, very rarely drops to
values like 5 and peaks at 64 (in real-time view). The number of
SqlAdapters varies between 0 and 1 (obviously).
The number of WeakReferences at the end of the run is 3 (two of them are
SqlClient related).

As I said before this is a perfectly normal allocation behavior, if you
observe different results running the same code, you must have a problem
with your set-up.

Willy.

Nov 17 '05 #20

"Frank" <fr***@frank.com> wrote in message
news:42***********************@news.xs4all.nl...
Willy,
at last!!!!!!!!!!!! I found it. I use [STAThread] in my main class.
Removing that leaves no live instances to weakreferences and adding it
gives lots of references.
Again, thanks for your help.

But, why does this line have this reaction?

Regards

Frank


Frank,

You should NEVER apply the STAThread attribute to the main entry of a
console application unless you pump the message queue.

f.i by calling DoEvents like in the sample I posted:

using System.Windows.Forms;
....
if (i % 1000 == 0)
{
Application.DoEvents();
Console.WriteLine(i);
}

The reason for this is that a thread that runs in a STA (Single Threaded
Apartment) can only be called by the Finalizer thread through
inter-apartment marshaling, this marshaling mechanism uses the windows
message queue, and requires the callee to pump the message queue (something
that gets done automatically in a Windows Forms application).
Failing to pump messages in the STA thread effectively blocks the Finalizer
to run, that means finalizable objects in the STA don't get released and
this is what happens here with the WeakReference instances.

Willy.

PS. That's why I asked to post the whole code BTW ;-)
Nov 17 '05 #21
[snip]
Willy.

PS. That's why I asked to post the whole code BTW
-) ----------------------------> You're right.


Willy,

the stathread is automatically inserted when u create a new console
application, so I never questioned it. Should have known better.

Thanks for your help.
Regards
Frank
Nov 17 '05 #22

"Frank" <fr***@frank.com> wrote in message
news:42***********************@news.xs4all.nl...
[snip]
Willy.

PS. That's why I asked to post the whole code
TW -) ----------------------------> You're right.


Willy,

the stathread is automatically inserted when u create a new console
application, so I never questioned it. Should have known better.

Thanks for your help.
Regards
Frank


It should not be done automatically, note this has been corrected in
whidbey.
VB.NET has this STAThread attribute implicitely set by the compiler, so
there you MUST set MTAThread explicitely.

Willy.


Nov 17 '05 #23

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Hemil | last post by:
Hello Friends, I need your help in resolving the above error message in my asp.net application. Surprisingly, when I build and run the solution on my local machine it works fine but I get the...
1
by: Horness | last post by:
McKirahan was kind enough to help me out with some code to open PDF's by entering the reference number contained in the file name. Many thanks for that (we've adapted it to work with other files...
13
by: Mike P | last post by:
I have, what should be, a simple scope problem. Can you help me fix this? I'm trying to end up like this: originalArray = and newArray = . Instead I wind up like this: originalArray = and...
5
by: sandman | last post by:
I've been testing my web app on another workstation to simulate using the server time. The test pc's time is an hour behind the server time and when the user processes a request, the server time...
2
by: Jake Barnes | last post by:
Using javascript closures to create singletons to ensure the survival of a reference to an HTML block when removeChild() may remove the last reference to the block and thus destory the block is...
7
by: Fred Hedges | last post by:
I'm wondering if a tool exists that will integrate with the VS 2005 debugger, such that when I set a breakpoint I can inspect a reference and see how many other references exist to that object. ...
3
by: Ole Nielsby | last post by:
I need to implement reference counting in a class hierarch, in a thread safe manner. (The classes are umanaged but I might want to compile them with the /clr option.) Some of the objects - atoms...
7
by: =?Utf-8?B?Sm9lbCBNZXJr?= | last post by:
I have created a custom class with both value type members and reference type members. I then have another custom class which inherits from a generic list of my first class. This custom listneeds...
1
by: msnews.microsoft.com | last post by:
Is there a way to re-add a web reference once it's been removed from a project without recreating all of code generated off of browsing to the wsdl? I was playing around with a few different...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.