Memory question when returning an object from inside another object

S

Steven Blair

Hi,

Quick overview of the problem:

public bool Something( out DataSet ds )
{
bool ret=false;

try
{
xmlDocument myXmlDoc = new xmlDocument( myFile.xml );

ds = myXmlDoc.DataSet;

ret=true;
}
catch( Exception e )
{
//Do something
}

return ret;
}

How would the memory for the xmlDocument get released? The object
calling this function would have a reference (correct me if I am wrong)
to the DataSet inside the xmlDocument, so would the c# memory manager
ignore this object?

I thought about replacing:

ds = myXmlDoc.DataSet;

with:

ds = myXmlDoc.DataSet.Copy();
myXmlDoc = null; //Would this allow memory to be released?

Any help on this would be appreciated.

Regards,

Steven
 
D

Dan Bass

I'm sure Jon Skeet will be watching and add his two pennies worth (which is
more than my opinions are valued at!) but I think it goes something like
this:

myXmlDoc is a variable that references an XmlDocument object. This
XmlDocument object is then referenced by a DataSet object. Therefore the
object is only "cleaned up" by the garbage collector when the object is no
longer being referenced either this XmlDocument variable or the DataSet
object... You don't need to call the Copy() method unless you want a
different object, copied from your original XmlDocument.

I do believe you can also do this:
public bool Something ( Dataset ds )
which passes in a reference to the dataset object. Therefore changes to this
object are reflected in the original.
 
J

Joakim Karlsson

I guess you mean XmlDataDocument, not XmlDocument?

I believe the XmlDataDocument will not be eligeble for GC if you
directly assign the XmlDataDocument.DataSet property to your out
parameter. The reason is that the XmlDataDocument registers event
handler methods with the DataSet in order to be able to update the
document as soon anything changes in the DataSet. This means that the
DataSet in fact has a reference (well several actually) to the
XmlDataDocument.

That aside, the code below will not work. The XmlDataDocument class does
not expose any constructor that takes a path to an XML-document, and the
XmlDocument class does not expose a DatSet property.

Is this really your repro case?

/Joakim
 
S

Steven Blair

Thanks for taking the time to reply.

The reason why there is a few typos is the source code isnt available to
me right now (its sitting on another PC which is locked atm)

Yes its a XmlDataDocument...

I can't remember the code directly, but I load a xml file into this
object. It might have a LoadXML mehtod.

So when I call ds = myXMLDoc.DataSet this prevents the XmlDataDocument
memory from being released... How would I ensure that the memory for
this object is released?

Another quick question:

ds = myXMLDoc.DataSet;

Would this create a new DataSet, or would ds be a reference to the
DataSet held inside the XMLDataDocument?

Regards,

Steven
 
J

Joakim Karlsson

Are you using the XmlDataDocument just to fill a DataSet with data?
Without needing the synchronization? Looking at your code example, I
think this would perform the same operation:

public bool Something( out DataSet ds )
{
bool ret=false;

try
{
ds = new DataSet();
ds.ReadXml( myFile.xml );

ret=true;
}
catch( Exception e )
{
//Do something
}

return ret;
}

Otherwise I guess you would have to use DataSet.Copy(), but that feels
like too much overhead.

Steven said:
Another quick question:

ds = myXMLDoc.DataSet;

Would this create a new DataSet, or would ds be a reference to the
DataSet held inside the XMLDataDocument?

That will return a reference to XmlDataDocument's dataSet member.

/Joakim
 
S

Steven Blair

Yeah looks like a little overkill I agree, but my workmate wrote the
code in the first place (seriously not passing the blame ;) ) and is
using a XSD file I think (this is not my area but I am assured it is
required). All the rows are then required to be loaded into a RDBMS, so
he uses the DataSet object from the xmlDataDocument.

He then uses a foreach (DataRow dr in ds.Tables[0],Rows) and calls a
Stored procedure to laod the transaction in.

Our first worry was the memory would never be released for the
xmlDataDocument, but I am sure the .Copy method will allow the memory to
be released.

Regards,

Steven
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,


AFAIK XmlDocument does not have a DataSet property. so the line

ds = myXmlDoc.DataSet;

will not compile


How would the memory for the xmlDocument get released? The object
calling this function would have a reference (correct me if I am wrong)
to the DataSet inside the xmlDocument, so would the c# memory manager
ignore this object?


The memory will be released after it's not longer used.

What happen depends of how the DataSet property is implemented ( at least in
theory, remember it does not exist ! )

XmlDocument keeps its data in an intermal data structure, it may be
something like a tree or a linked list. IF the dataset can use the same one
it would simple get a reference to it , if not it may transform it to its
intermal representation used. If DataSet kept a reference it will not
deleted once the XmlDocumet instance is out of scope, otherwise once the
XmlDocument is uit of scope the GC will recall the memory.


Hope you understand the above, it's a complex thing to explain and maybe my
english is not clear enough :)

Cheers,
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,


I would try to use the DataSet directly this will save you an innecesary
step, if this is not possible then try to use the XmlDataDocument directly,
I see no neeed to use both if all what you want is store the data in a RDBMS
, you could iterate in the Data nodes of the XML document and create the
SqlCommands directly from there, no need to create a dataset.

Cheers,
 
J

James Curran

Steven Blair said:
How would the memory for the xmlDocument get released? The object
calling this function would have a reference (correct me if I am wrong)
to the DataSet inside the xmlDocument, so would the c# memory manager
ignore this object?

Speaking to the general case (ie, ignoring issues specific to
XmlDataDocument that others have addressed): There is no DataSet "inside"
the xmlDocument. There is a DataSet and there is an XmlDocument. The
XmlDocument holds a reference to the DataSet, and something else also holds
a reference to the DataSet. Once the function ends, nothing will hold a
reference to the XmlDocument, so it will be released -- releasing it's
reference to the DataSet in the process. The DataSet will remain, as there
remains a reference to it.

--
Truth,
James Curran
[erstwhile VC++ MVP]
Home: www.noveltheory.com Work: www.njtheater.com
Blog: www.honestillusion.com Day Job: www.partsearch.com
 
S

Steven Blair

James,

Thats makes things a bit clearer. I assumed the DataSet was part of the
xmlDataDocument.

One thing which still puzzles me is the releasing of the memory for the
xmlDataDocument.

IF I did this:

return xmlDataDocument.DataSet; //pass to calling func

Would the xmlDataDocument get released by the memory manager after the
fucntion has been called, even if the DataSet return was still getting
used?

This is what I am more confused on than anything.

Regards,

Steven
 
J

James Curran

Steven Blair said:
IF I did this:

return xmlDataDocument.DataSet; //pass to calling func

Would the xmlDataDocument get released by the memory manager after the
fucntion has been called, even if the DataSet return was still getting
used?

Certainly. Remember, "xmlDataDocument.DataSet" is just a variable
holding a reference to a DataSet object which lives elsewhere. It's
exactly as if you had written:

DataSet ds = xmlDataDocument.DataSet;
return ds;

Actually, it's more like:

DataSet ds = new DataSet();
// fill ds
xmlDataDocument.DataSet = ds;
return ds;

except you didn't show the first part.


--
Truth,
James Curran
[erstwhile VC++ MVP]
Home: www.noveltheory.com Work: www.njtheater.com
Blog: www.honestillusion.com Day Job: www.partsearch.com
 

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