memory allocation/leak problem

  • Thread starter Thread starter dudi
  • Start date Start date
D

dudi

I am encountering the following strange problem which causes the application
to use more memory then it should.
I have 5 database tables. lets pretend I want to load each one of them into
a dataTable. then, run over all the rows of the dataTable and for each cell
in the dataRow concatenate a string (the value in the cell is a string to
begin with).
I expect the memory to go up every time I load a dataTable, even go up when
I modify the rows, but I expect it to
go down when the loop ends and then go up again when the new dataTable is
loaded. however, the memory simply adds-up... each dataTable just adds to
the memory and it is as if the last dataTable is not releases. more
precisely, I found the problem is not the dataTable but the strings. it
seems the string (new, old) that I modify are not cleared from the memory.
here is a sample of what I do and causes the memory 'leak'. below this
sample I also specify what I did that DOES work (seems to have no memory
build up), however, that solution is not acceptable:

'------------------------
Dim tables() As String = {"5Tbl", "4Tbl", "3Tbl", "2Tbl", "1Tbl"}
For Each table As String In tables
Console.WriteLine("loading table:" + table)
'loads the table into memory
Dim dt As DataTable
Dim sqlIns As String = "SELECT * FROM " + table
dt = m_dbMaster.getDataTable(sqlIns)

'added this just to make sure
System.GC.Collect()
System.GC.WaitForPendingFinalizers()
System.GC.Collect()

System.Threading.Thread.Sleep(5000)
Console.WriteLine("working table:" + table)
Dim dr As DataRow
For Each dr In dt.Rows
dr("w1") = CStr(dr.Item("w1"))
dr("w2") = CStr(dr.Item("w2"))
dr("w3") = CStr(dr.Item("w3"))
dr("w4") = CStr(dr.Item("w4"))
Next
System.Threading.Thread.Sleep(5000)
'------------------------

OK, so before you tell me it is probably the getDataTable function that is
not working well hear this:
if I change the lines
dr("w1") = CStr(dr.Item("w1")) to
dr("w1") = "xxxxxxxxxxxxxxxxxxxx" (that is, I am replacing the value in the
cell with a literal instead of a string generated from its original value)
the EVERYTHING IS JUST FINE!!! memory goes up and down as it is supposed to.
anyone has any idea what is going on?

regards and thanks in advance.
 
Hi,
First of all, what is the real purpose of something like this??
dr("w1") = CStr(dr.Item("w1"))
Secondly, I would recommend not to use CStr. Use the ToString instead or
DirectCast datarow items to System.String (if the type of the Item is
String)
Finally, why on earth are you doing this???

System.GC.Collect()
System.GC.WaitForPendingFinalizers()
System.GC.Collect()

The overhead involved in what you have done is something I cannot really
comprehend. It is absolutely not required in your case. If at all you are
done with using an object somewhere in a program, set it to nothing (taking
out of scope). The GC will be called automatically when situation demands(
you memory is really scarce). Leave it to the rutime to decide when
collection is required.
 
I guess he says there is a problem, and he wrote a number of lines to prove
his point. What are you saying, that there is no such problem, or that one
should program in a certain way to avoid the problem?


Manoj G said:
Hi,
First of all, what is the real purpose of something like this??
dr("w1") = CStr(dr.Item("w1"))
Secondly, I would recommend not to use CStr. Use the ToString instead or
DirectCast datarow items to System.String (if the type of the Item is
String)
Finally, why on earth are you doing this???

System.GC.Collect()
System.GC.WaitForPendingFinalizers()
System.GC.Collect()

The overhead involved in what you have done is something I cannot really
comprehend. It is absolutely not required in your case. If at all you are
done with using an object somewhere in a program, set it to nothing (taking
out of scope). The GC will be called automatically when situation demands(
you memory is really scarce). Leave it to the rutime to decide when
collection is required.
--
HTH,
Manoj G [.NET MVP]
http://www15.brinkster.com/manoj4dotnet

dudi said:
I am encountering the following strange problem which causes the application
to use more memory then it should.
I have 5 database tables. lets pretend I want to load each one of them into
a dataTable. then, run over all the rows of the dataTable and for each cell
in the dataRow concatenate a string (the value in the cell is a string to
begin with).
I expect the memory to go up every time I load a dataTable, even go up when
I modify the rows, but I expect it to
go down when the loop ends and then go up again when the new dataTable is
loaded. however, the memory simply adds-up... each dataTable just adds to
the memory and it is as if the last dataTable is not releases. more
precisely, I found the problem is not the dataTable but the strings. it
seems the string (new, old) that I modify are not cleared from the memory.
here is a sample of what I do and causes the memory 'leak'. below this
sample I also specify what I did that DOES work (seems to have no memory
build up), however, that solution is not acceptable:

'------------------------
Dim tables() As String = {"5Tbl", "4Tbl", "3Tbl", "2Tbl", "1Tbl"}
For Each table As String In tables
Console.WriteLine("loading table:" + table)
'loads the table into memory
Dim dt As DataTable
Dim sqlIns As String = "SELECT * FROM " + table
dt = m_dbMaster.getDataTable(sqlIns)

'added this just to make sure
System.GC.Collect()
System.GC.WaitForPendingFinalizers()
System.GC.Collect()

System.Threading.Thread.Sleep(5000)
Console.WriteLine("working table:" + table)
Dim dr As DataRow
For Each dr In dt.Rows
dr("w1") = CStr(dr.Item("w1"))
dr("w2") = CStr(dr.Item("w2"))
dr("w3") = CStr(dr.Item("w3"))
dr("w4") = CStr(dr.Item("w4"))
Next
System.Threading.Thread.Sleep(5000)
'------------------------

OK, so before you tell me it is probably the getDataTable function that is
not working well hear this:
if I change the lines
dr("w1") = CStr(dr.Item("w1")) to
dr("w1") = "xxxxxxxxxxxxxxxxxxxx" (that is, I am replacing the value in the
cell with a literal instead of a string generated from its original value)
the EVERYTHING IS JUST FINE!!! memory goes up and down as it is supposed to.
anyone has any idea what is going on?

regards and thanks in advance.
 
Hello David,

Thanks for posting in the group.

Manoj: I think the main purpose of GC.Collect() here is to make sure that
garbage collection is executed in the beginning of the loop so that the
memory usage is shown appropriately.

David: I didn't notice it before. But as Manoj mentioned, please try to
revise CStr to dr.Item("w1").ToString. After that, please test it on your
side to see if the memory usage is still growing. Please also post here
with how you check the memory usage of it, from task manager or etc.

Please post here with your testing results and we will follow up it here.
Thanks.

Best regards,
Yanhong Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.

--------------------
!From: "dudi" <[email protected]>
!Subject: memory allocation/leak problem
!Date: Mon, 20 Oct 2003 18:14:46 -0700
!Lines: 55
!X-Priority: 3
!X-MSMail-Priority: Normal
!X-Newsreader: Microsoft Outlook Express 6.00.2800.1158
!X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165
!Message-ID: <[email protected]>
!Newsgroups: microsoft.public.dotnet.framework
!NNTP-Posting-Host: 209-77-216-34.utopy.com 209.77.216.34
!Path:
cpmsftngxa06.phx.gbl!cpmsftngxa10.phx.gbl!TK2MSFTNGXA05.phx.gbl!TK2MSFTNGP08
.phx.gbl!tk2msftngp13.phx.gbl
!Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.framework:56631
!X-Tomcat-NG: microsoft.public.dotnet.framework
!
!I am encountering the following strange problem which causes the
application
!to use more memory then it should.
!I have 5 database tables. lets pretend I want to load each one of them into
!a dataTable. then, run over all the rows of the dataTable and for each cell
!in the dataRow concatenate a string (the value in the cell is a string to
!begin with).
!I expect the memory to go up every time I load a dataTable, even go up when
!I modify the rows, but I expect it to
!go down when the loop ends and then go up again when the new dataTable is
!loaded. however, the memory simply adds-up... each dataTable just adds to
!the memory and it is as if the last dataTable is not releases. more
!precisely, I found the problem is not the dataTable but the strings. it
!seems the string (new, old) that I modify are not cleared from the memory.
!here is a sample of what I do and causes the memory 'leak'. below this
!sample I also specify what I did that DOES work (seems to have no memory
!build up), however, that solution is not acceptable:
!
!'------------------------
!Dim tables() As String = {"5Tbl", "4Tbl", "3Tbl", "2Tbl", "1Tbl"}
!For Each table As String In tables
!Console.WriteLine("loading table:" + table)
!'loads the table into memory
!Dim dt As DataTable
!Dim sqlIns As String = "SELECT * FROM " + table
!dt = m_dbMaster.getDataTable(sqlIns)
!
!'added this just to make sure
!System.GC.Collect()
!System.GC.WaitForPendingFinalizers()
!System.GC.Collect()
!
!System.Threading.Thread.Sleep(5000)
!Console.WriteLine("working table:" + table)
!Dim dr As DataRow
!For Each dr In dt.Rows
!dr("w1") = CStr(dr.Item("w1"))
!dr("w2") = CStr(dr.Item("w2"))
!dr("w3") = CStr(dr.Item("w3"))
!dr("w4") = CStr(dr.Item("w4"))
!Next
!System.Threading.Thread.Sleep(5000)
!'------------------------
!
!OK, so before you tell me it is probably the getDataTable function that is
!not working well hear this:
!if I change the lines
!dr("w1") = CStr(dr.Item("w1")) to
! dr("w1") = "xxxxxxxxxxxxxxxxxxxx" (that is, I am replacing the value in
the
!cell with a literal instead of a string generated from its original value)
!the EVERYTHING IS JUST FINE!!! memory goes up and down as it is supposed
to.
!anyone has any idea what is going on?
!
!regards and thanks in advance.
!
!
!
 
thanks Chris for defending me (-: ...
To answer Manoj:
well the purpose is to show that there are one of 2 problems here, either
that for some reason, if the dataRow item is being used (by being on the
right side of a '=' operator) then it's memory is magically un-collectable,
or that it has nothing to do with the dataRow, but Strigns in general are
not being de-allocated by the GC. of course my application doesnt do that
exact line, but the 'best practices' of trying to get help usually demand to
boil the code down to the most trivial sample that shows the problem...
pretend that I am concatenating something to the original value of that
cell....
I tried ToString, it gave not better resutls. however I understand the
motivation which might be to avoid creating a new object/string... I am not
sure why would the implemantation of CStr be any different then ToString,
after all string are Immutable and a new string MUST be created also when
using ToString...
To avoid getting a reply in this Thread telling me to do this...

regards,
 
I forgot to mention: to understand the memory graphs I sent, especially the
literal one you need to understand that not all tables are of the same size,
the middle ones are bigger, that is why the memory looks like a hill, the
important thing is that the literal version goes up and DOWN at some point,
while the toString (and CStr) verision just goes up and up and up...
 
In the old days of C++ when expecting a memory leak, it was no good looking
at the overall system memory usage in order to obtain the true picture. One
had to run the Performance Monitor, then monitor the Private Bytes of the
Process in question. I'm not sure if this is the case with DOTNET as well.
Do you care to comment on this, or get the opinion of your colleagues?

I've seen so many postings regarding memory leaks. Can't MS write an
article regarding this topic and explain the behavior/expected results, etc,
etc?

Thanks.
 
Hello David,

Thanks for the quick response.

I will test it on my side and discuss with our tech experts on it. We will
get back here as soon as possible.

Please post here if you have any more concerns.

Best regards,
Yanhong Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.

--------------------
!From: "dudi" <[email protected]>
!References: <[email protected]>
<[email protected]>
<#[email protected]>
!Subject: Re: memory allocation/leak problem
!Date: Tue, 21 Oct 2003 10:25:13 -0700
!Lines: 7
!X-Priority: 3
!X-MSMail-Priority: Normal
!X-Newsreader: Microsoft Outlook Express 6.00.2800.1158
!X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165
!Message-ID: <#[email protected]>
!Newsgroups: microsoft.public.dotnet.framework
!NNTP-Posting-Host: 209-77-216-34.utopy.com 209.77.216.34
!Path:
cpmsftngxa06.phx.gbl!cpmsftngxa09.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFTNGP11.
phx.gbl
!Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.framework:56717
!X-Tomcat-NG: microsoft.public.dotnet.framework
!
!I forgot to mention: to understand the memory graphs I sent, especially the
!literal one you need to understand that not all tables are of the same
size,
!the middle ones are bigger, that is why the memory looks like a hill, the
!important thing is that the literal version goes up and DOWN at some point,
!while the toString (and CStr) verision just goes up and up and up...
!
!
!
 
Hello David,

Thanks for your detailed information.

I also thought of that. Moving the string operation part into a single
function may have better effect in GC collection. In fact, what I think of
first is that even when opening table and string operation part are in one
single function, we could call GC.Collect before calling this function and
call GC.Collect after this function to see if the memory grows. like:
GC.Collect()
TestFunc()
GC.Collect()

I think this may not be a leak problem. It should be related to how GC
collects those string data under different situations. Maybe in a function,
some references are not released completely so that this memory is not
released.

If you want to dig more, could you please create a simple sample and email
it to us? We need to debug its memory usage to try to get more info. Please
remove online from my email address to reach me. Thanks again for working
with me so closely.

Best regards,
Yanhong Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 
While I am sure the end result of this will be that this is not a bug or a
memory leak, but a well documented feature of .NET (-; my way of defining
this would be to show the code I am about to show you to 10 .NET developers,
and ask them if they expect a different memory behavior from the 2 different
code options. I bet 9 out of 10 will expect no difference (especially the
fact that the ENDING memory usage level is so different, not to mention the
behavior of the memory while the function is running). if i am correct, and
9 out of 10 will expect no difference then I would call this a bad .NET
behavior, bug or not.

Here is the new information I found per your request (-: .
I tried making a small program to duplicate the problem using arrayList...
could not. arraylist behaved like a perfect student. I went back to using a
dataTable, the code below contains 3 functions:
*getDT(int) which is used to build a dataTable, integer is used to make sure
the strings in the dataTable are different for each loop.
*doOneTable(int) does all the work of loading a DT, changing its strings,
and doing nothing with it
*memLeakTest() is the driver of the test (call it from a form's button for
example). here is where we change the code a bit to show the 'good' and the
'bad' behavior.

Public Function getDT(ByVal i As Integer) As DataTable
Dim dt As New DataTable
dt.Columns.Add("w1", GetType(String))
dt.Columns.Add("w2", GetType(String))
dt.Columns.Add("w3", GetType(String))
For j As Integer = 0 To 400000
Dim newRow As DataRow = dt.NewRow()
newRow("w1") = "w1aaaaaaaa" + i.ToString + j.ToString
newRow("w2") = "w2aaaaaaaa" + i.ToString + j.ToString
newRow("w3") = "w3aaaaaaaa" + i.ToString + j.ToString
dt.Rows.Add(newRow)
Next
Return dt
End Function

Public Sub doOneTable(ByVal j As Integer)
'-------worker code start-------------
Dim dt As DataTable
System.Threading.Thread.Sleep(4000)
Console.WriteLine("get dataTable:" + j.ToString)
dt = getDT(j)
Console.WriteLine("sleep")
System.Threading.Thread.Sleep(4000)
Console.WriteLine("going over dt")
Dim dr As DataRow
For Each dr In dt.Rows
dr("w1") = CStr(dr("w1")) + j.ToString + "xxxxxxxxxxxxxxx"
dr("w2") = CStr(dr("w2")) + j.ToString + "xxxxxxxxxxxxxxx"
dr("w3") = CStr(dr("w3")) + j.ToString + "xxxxxxxxxxxxxxx"
Next
Console.WriteLine("end")
'-------worker code end-------------
End Sub

Here is where you need to change the code between the two runs to see the
good and bad memory behavior
for the good version, use the doOneTalbe(j) line (remove the comment) and
put al the rest of the code between
the '-------worker code start------------- and '-------worker code
end------------- in a comment. to see the bad version reverse this
commenting.
you will notice 2 things:
memory builds up and gets collected when using the doOneTable version,
however, it mostly builds up when using the worker code in the
main function. the end memory (after the program ends) is much higher in the
'bad' version.
Notice also that if you do not use the gc.collect code, then the 2 versions
seem to work more or less the same way (bad!).

Public Sub memLeakTest()
Console.WriteLine("start:")
For j As Integer = 1 To 5
'doOneTable(j) 'use this line to see the good version
'-------worker code start-------------
'use this section to see the bad version
Dim dt As DataTable
System.Threading.Thread.Sleep(4000)
Console.WriteLine("get dataTable:" + j.ToString)
dt = getDT(j)
Console.WriteLine("sleep")
System.Threading.Thread.Sleep(4000)
Console.WriteLine("going over dt")
Dim dr As DataRow
For Each dr In dt.Rows
dr("w1") = CStr(dr("w1")) + j.ToString + "xxxxxxxxxxxxxxx"
dr("w2") = CStr(dr("w2")) + j.ToString + "xxxxxxxxxxxxxxx"
dr("w3") = CStr(dr("w3")) + j.ToString + "xxxxxxxxxxxxxxx"
Next
Console.WriteLine("end")
'-------worker code end-------------

System.GC.Collect()
System.GC.WaitForPendingFinalizers()
System.GC.Collect()
Next
End Sub

Let me know if this was clear and you managed to reproduce the different
memory behavior using this sample.
regards.
 
Hello,

Thanks very much for the detailed response. I will look into it and reply
you with more information.

Best regards,
Yanhong Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 
is anyone working on this?
I think my sample program proves there is a problem with the .NET framework,
I found no documentation that can explain this behavior (not saying this is
a bug, just that **I** can not explain this).
I know you suggested I use memory dumps to understand what is going on... I
have no time for this since I did found a good work around. I can not
justify 3 days of debugging the Framework. however I think MS should either
point us to the documentation saying 'this is just great and how we wanted
it to be' or deal with this as a Framework GC bug and tell us what is the
status.

Regards.
 
Hello,

I am still here. I sent a email to Ernan Guelman, but no reply. So I
assumed it was OK for you.

We will look into it and post more information here. Thanks.

Best regards,
Yanhong Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 
Hi David, this falls under the category of As Scotty said, the more they try to overtake the plumbing the easier it is to stop up the drain...

I looked at the code Yan-Hong sent to me and the first thing I noticed is that you were not disposing of the objects you created between iterations of the loops, thats why it works
when you put it in a seperate sub because the objects are disposed of after the return. If you add the following lines to your Worker code it behaves the same way as it does by
sending it to the other subroutine...

Public Sub memLeakTest()
Console.WriteLine("start:")

For j As Integer = 1 To 5
'doOneTable(j) 'use this line to see the good version
'-------worker code start-------------
'use this section to see the bad version
Dim dt As DataTable
System.Threading.Thread.Sleep(4000)
Console.WriteLine("get dataTable:" + j.ToString)
dt = getDT(j)
Console.WriteLine("sleep")
System.Threading.Thread.Sleep(4000)
Console.WriteLine("going over dt")
Dim dr As DataRow
For Each dr In dt.Rows
dr("w1") = CStr(dr("w1")) + j.ToString + "xxxxxxxxxxxxxxx"
dr("w2") = CStr(dr("w2")) + j.ToString + "xxxxxxxxxxxxxxx"
dr("w3") = CStr(dr("w3")) + j.ToString + "xxxxxxxxxxxxxxx"
Next

Console.WriteLine("end")
'ADD THESE LINES
dr = Nothing
dt.Clear()
dt.Dispose()
dt = Nothing
'
'-------worker code end-------------

then the Memory falls back off like it is supposed to... This was a common problem with Recordsets in ADO. And while the new fangled Garbage Collection is supposed to do alot,
it wont clean up objects that have not been disposed of first... (Eventually it would have cleared the memory, but probably not as soon as you would have liked) by disposing of
your objects you get rid of them almost immediately...

Scot Rose, MCSD
Microsoft Visual Basic Developer Support
Email : (e-mail address removed) <Remove word online. from address>

This posting is provided “AS IS”, with no warranties, and confers no rights.

Get Secure!
http://www.microsoft.com/security
http://www.microsoft.com/protect


--------------------
 
hi Scot, thanks for the reply and giving some explanations there.
trying to make it more clear:

I have 2 problems with your answer which stats that calling Dispose is the
right thing to do and should be expected:
1) you told me that when loosing the references to the dataTable once the
variable referencing it (dt) was declared in a function the framework
understands the dataTable is no longer in used and will call its Dispose.
how is that any different from loosing the reference (again dt) that in this
case was declared inside a for loop? once the next 'for' iteration executes,
the variable dt is out of scope and the old dataTable is left without any
reference to it. the same as in the function case. in terms of memory
references the cases are the same, why doesn't the GC understands that no
one will *ever* be able to use this dataTable and collect it?
2) All of this behaves in a rational way (rational = the way i expect it
:-) ) when you repeat all of this test with an ArrayList. ArrayList behaves
like a normal obj, once it has no references to it it goes... (the ArrayList
was also populated with strings).
what is the reason that this 'strange' behavior by the dataTable is the
correct behavior? why in this case (and as far as I know, this is the only
data structure that gives me this problem) it is not good enough to have no
more references to the dataTAble but u have to explicitly call Dispose just
before the reference goes out of scope... ?

Dispose is mention in books as something that is needed to guarantee that we
free up resources such as a DB connection or file. but in those cases we can
always do the right thing which is calling connection.close or file.close,
i.e handling the resources responsibly, here I am expected to call
dataTable.Dispose() but there are no known 'magical' resources that I need
to free and I see no difference between a dataTable and an arrayList: once
they have no reference to them, they have no reason to be, and they have no
resources (except for the data in them) that needs to be freed.

can you shade your light on this? is this dataTable behavior a good thing in
your opinion?

regards.

Scot Rose said:
Hi David, this falls under the category of As Scotty said, the more they
try to overtake the plumbing the easier it is to stop up the drain...
I looked at the code Yan-Hong sent to me and the first thing I noticed is
that you were not disposing of the objects you created between iterations of
the loops, thats why it works
when you put it in a seperate sub because the objects are disposed of
after the return. If you add the following lines to your Worker code it
behaves the same way as it does by
sending it to the other subroutine...

Public Sub memLeakTest()
Console.WriteLine("start:")

For j As Integer = 1 To 5
'doOneTable(j) 'use this line to see the good version
'-------worker code start-------------
'use this section to see the bad version
Dim dt As DataTable
System.Threading.Thread.Sleep(4000)
Console.WriteLine("get dataTable:" + j.ToString)
dt = getDT(j)
Console.WriteLine("sleep")
System.Threading.Thread.Sleep(4000)
Console.WriteLine("going over dt")
Dim dr As DataRow
For Each dr In dt.Rows
dr("w1") = CStr(dr("w1")) + j.ToString + "xxxxxxxxxxxxxxx"
dr("w2") = CStr(dr("w2")) + j.ToString + "xxxxxxxxxxxxxxx"
dr("w3") = CStr(dr("w3")) + j.ToString + "xxxxxxxxxxxxxxx"
Next

Console.WriteLine("end")
'ADD THESE LINES
dr = Nothing
dt.Clear()
dt.Dispose()
dt = Nothing
'
'-------worker code end-------------

then the Memory falls back off like it is supposed to... This was a common
problem with Recordsets in ADO. And while the new fangled Garbage Collection
is supposed to do alot,
it wont clean up objects that have not been disposed of first...
(Eventually it would have cleared the memory, but probably not as soon as
you would have liked) by disposing of
your objects you get rid of them almost immediately...

Scot Rose, MCSD
Microsoft Visual Basic Developer Support
Email : (e-mail address removed) <Remove word online. from address>

This posting is provided "AS IS", with no warranties, and confers no rights.

Get Secure!
http://www.microsoft.com/security
http://www.microsoft.com/protect


--------------------
@TK2MSFTNGP11.phx.gbl> <x#[email protected]>
 
I'll start with your last question first:
can you shade your light on this? is this dataTable behavior a good thing in
your opinion?

Nope, I think there should be some consistancy between the way all of the objects are handled.. That said however I do not know how this particular object is handled under the
covers and there may have been some logical (albiet unknown) reason for it to which I cannot answer.

For the rest of it, I offered up the Dispose option for the simple expediency that it does work (As closing and setting to nothing did to objects in VB6). When I looked at your code
sample, it was the first thing that came to mind (Knowing that it was a scoping issue since it worked when the table went out of scope in your other subroutine) I tend to be a Practical
programmer rather than a theoretical one. When I find something that works, I simply use it. I know of several people that have spent hours going over decompiles of sourcecode
looking for answers to a problem, when the answer is simply 'thats the way it behaves'. Some of them are here in the newsgroups and I would love it if they would jump in here with
an exact answer for why the DataTable behaves this way and not another.

I have been burned by Memory leaks before... If I had written the code you sent, I would probably have used dispose even in the subroutine. I have never been so certain of
'automagical' ways of doing things (Like Garbage collection) that I would be able to trust it in my own projects<G>


Scot Rose, MCSD
Microsoft Visual Basic Developer Support
Email : (e-mail address removed) <Remove word online. from address>

This posting is provided “AS IS”, with no warranties, and confers no rights.

Get Secure!
http://www.microsoft.com/security
http://www.microsoft.com/protect


--------------------
@TK2MSFTNGP11.phx.gbl> <x#[email protected]> <[email protected]> <PuhCWTUmDHA.1792
 
Back
Top