I have some C# code that reads a huge file, and after some manipulation, sets its reference to null and exits the function, but the memory won't free up.
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xmlString);
XmlService.ConvertExcelToXML(xmlDoc);
int sdfid = 320;
XmlService.CompareXML(xmlDoc, ref sdfid, pkid);
xmlDoc.RemoveAll();
xmlDoc = null;
The xmlDoc
is a very big string, usually around 50 MB. When I exit the function, that memory is permamnently occupied, and I have to restart my service couple of times a day, otherwise it's memory usage reaches 1GB.
I have tried to use GC.Collect, but no use.
Thank you in advance.
Edit
Here is the class declaration for XmlService. It has no variables. All methods are static
public class XmlService
ConvertExcelToXML function's code
public static bool ConvertExcelToXML(XmlDocument xmlDoc) {
XmlNamespaceManager nm = new XmlNamespaceManager(xmlDoc.NameTable);
nm.AddNamespace("z", "urn:schemas-microsoft-com:office:spreadsheet");
nm.AddNamespace("o", "urn:schemas-microsoft-com:office:office");
nm.AddNamespace("x", "urn:schemas-microsoft-com:office:excel");
nm.AddNamespace("ss", "urn:schemas-microsoft-com:office:spreadsheet");
nm.AddNamespace("html", "http://www.w3.org/TR/REC-html40");
XmlNodeList rows = xmlDoc.DocumentElement.SelectNodes("//z:Worksheet/z:Table/z:Row", nm);
if (rows != null && rows.Count > 0)
{
XmlNode nodeNames = rows[0];
XmlNode nodeValues = rows[1];
XmlNode destRootNode = xmlDoc.CreateNode(XmlNodeType.Element, "ParentNode", null);
XmlNode fieldNode = null;
XmlNode dataNode = null;
for (int i = 0; i < nodeNames.ChildNodes.Count; i++)
{
if (nodeNames.ChildNodes[i].HasChildNodes)
{
string nodeName = nodeNames.ChildNodes[i].ChildNodes[0].InnerXml;
//string nodeValue = nodeValues.ChildNodes[i].ChildNodes[0].InnerXml;
string nodeValue = "DataField" + i.ToString();
fieldNode = xmlDoc.CreateNode(XmlNodeType.Element, "Field", null);
dataNode = xmlDoc.CreateNode(XmlNodeType.Element, "Data", null);
dataNode.InnerXml = nodeName;
fieldNode.AppendChild(dataNode);
destRootNode.AppendChild(fieldNode);
fieldNode = xmlDoc.CreateNode(XmlNodeType.Element, "Field", null);
dataNode = xmlDoc.CreateNode(XmlNodeType.Element, "Data", null);
dataNode.InnerXml = nodeValue;
fieldNode.AppendChild(dataNode);
destRootNode.AppendChild(fieldNode);
}
}
xmlDoc.LoadXml("<ParentNode>" + destRootNode.InnerXml + "</ParentNode>");
return true;
}
return false;
}
and Code for CompareXML
public static void CompareXML(XmlDocument filexmlDoc, ref int maxSDFID, string PKID)
{
FieldsListBO tmpFieldListBO = null;
ResponseDTO responseDTO = DbService.getConnection();
DbConnection con = (DbConnection)responseDTO.ReturnedObjects[Constants.CONNECTION_OBJECT];
DbProviderFactory factory = (DbProviderFactory)responseDTO.ReturnedObjects[Constants.FACTORY_OBJECT];
DbCommand cmd = factory.CreateCommand();
cmd.CommandText = "select * from tree_store";
cmd.Connection = con;
con.Open();
DbDataReader dr = cmd.ExecuteReader();
dr.Read();
String pXmlizedString = (String)dr["TransactionTree"];
dr.Dispose();
cmd.Dispose();
con.Dispose();
XmlSerializer xs = new XmlSerializer(typeof(FieldsListBO));
MemoryStream memoryStream = new MemoryStream(StringToUTF8ByteArray(pXmlizedString));
XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.ASCII);
tmpFieldListBO = (FieldsListBO)xs.Deserialize(memoryStream);
memoryStream.Dispose();
xmlTextWriter.Close();
if (tmpFieldListBO.FieldsList.Count < 1)
{
maxSDFID = 0;
return;
}
FieldsListBO fieldListBO = new FieldsListBO();
for (int i = 0; i < tmpFieldListBO.FieldsList.Count; i++)
{
if (tmpFieldListBO.FieldsList[i]._pkid.Equals(PKID))
{
fieldListBO.FieldsList.Add(tmpFieldListBO.FieldsList[i]);
}
}
GetMaxSDFID(filexmlDoc, ref maxSDFID, fieldListBO);
}
filexmlDoc being passed to GetMaxSDFID is just being transversed node by node no update/delation is done