即使退出该function,.NET内存也无法释放

我有一些C#代码读取一个巨大的文件,经过一些操作后,将其引用设置为null并退出该函数,但内存不会释放。

XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(xmlString); XmlService.ConvertExcelToXML(xmlDoc); int sdfid = 320; XmlService.CompareXML(xmlDoc, ref sdfid, pkid); xmlDoc.RemoveAll(); xmlDoc = null; 

xmlDoc是一个非常大的字符串,通常大约50 MB。 当我退出该function时,该内存永久占用,我必须每天重启我的服务几次,否则它的内存使用量达到1GB。

我曾尝试使用GC.Collect,但没有用。

先感谢您。

编辑

这是XmlService的类声明。 它没有变数。 所有方法都是静态的

  public class XmlService 

ConvertExcelToXML函数的代码

 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("" + destRootNode.InnerXml + ""); return true; } return false; } 

和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); } 

传递给GetMaxSDFID的filexmlDoc只是逐个节点地被横向移动而没有更新/放弃

我很抱歉这样说,我可能错了,但看起来真的在猜测问题的根源。

我说这是因为你试图做的。 取消一个局部变量并调用GC.Collect,希望能解决这个问题。 有经验的人会告诉你这不是它,也无济于事。

猜测通常是一种很好的方法(例如,其他人已经猜到了XmlService.ConvertExcelToXML可能是一个问题),但是为什么当你没有必要时猜测,当你的应用程序消耗了大量内存时,获取进程的内存转储。 您可以使用ProcDump,但还有许多其他方法可以执行此操作。

安装WinDbg 。 使用此工具,您可以使用!dumpheap –stat等命令分析内存转储,该命令可以准确地告诉您1 GB的!dumpheap –stat

我们需要知道XmlService作用,以便更多地了解正在发生的事情。 它可以很容易地存储数据由于某种原因(或者除了糟糕的设计之外没有其他原因)。

假设该方法在您向我们展示的代码之后不久结束,您肯定不需要将该变量设置为null,并且如果XmlService没有持有对该对象的引用,则您也不需要调用RemoveAll

请注意, XmlDocument对象本身不会很大,尽管它的对象图可能是。 xmlString本身可能很大 – 如果最终在大对象堆上有很多对象,这可能会给你带来麻烦,因为即使在释放空间后LOH也不会被压缩。 我不希望它表现得像这样。

您是否必须将XML转换为字符串变量? 你可以流式传输它(例如从文件中)吗?