2011-05-01 44 views
3

我有一些C#代碼,它讀取巨大的文件,經過一些操作後,將其引用設置爲null並退出函數,但內存不會釋放。即使退出函數後,.NET內存也不能釋放

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。當我退出該功能時,該內存被永久佔用,而且我必須每天重新啓動我的服務幾次,否則內存使用量將達到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("<ParentNode>" + destRootNode.InnerXml + "</ParentNode>"); 
      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); 
    } 

filexmlDoc傳遞給GetMaxSDFID只是被transversed由節點節點沒有更新/ delation完成

+1

發佈了XmlService.ConvertExcelToXML和XmlService.CompareXML的代碼 – 2011-05-01 07:39:15

+2

我懷疑問題出在'XmlService'方法 - 它有沒有可能是不安全/非託管代碼?另一個選擇是它使用'static'變量,從而將它保存在內存中。 – 2011-05-01 07:40:04

+0

你確定這段代碼導致了這個問題嗎?如何完成Excel轉換?或者在CompareXML方法中做了什麼。 – ChristiaanV 2011-05-01 07:40:07

回答

2

我們需要知道XmlService在ord中的作用呃更多地瞭解正在發生的事情。它可以很容易地存儲數據出於某種原因(或者除了糟糕的設計之外可能沒有理由)。

假設該方法在您向我們展示的代碼後不久就結束,那麼您絕對不需要將此變量設置爲null,並且如果XmlService未持有對該對象的引用,那麼您不需要請致電RemoveAll

請注意,XmlDocument對象本身不會很大,雖然它的對象圖可能是。 xmlString本身可能雖然大 - 如果最終在大型對象堆中有很多對象,那可能會給您帶來問題,因爲即使空間被釋放後LOH也不會被壓縮。儘管如此,我不會期望它表現得像這樣。

您是否有將XML轉換爲字符串變量以開始?您可以將它流式傳輸(例如從文件中)嗎?

+0

奧斯威戈湖高? – corlettk 2011-05-01 07:45:28

+0

大對象堆:) - 用於超過80K大小的對象 – 2011-05-01 07:48:30

4

我很抱歉地說,我可能是錯的,但它真的看起來就像你猜測問題的根源。

我說這是因爲你試圖做的。取消一個局部變量並調用GC.Collect,希望這能解決它。有經驗的人會告訴你,這不是,也無濟於事。

猜測通常是一種很好的方法(例如其他人猜測XmlService.ConvertExcelToXML可能是一個問題),但爲什麼猜你什麼時候不需要,當你的應用程序消耗了大量的記憶。您可以使用ProcDump,但還有很多其他方法可以執行此操作。

安裝WinDbg。使用此工具,您可以使用​​等命令分析您的內存轉儲,這些命令可以準確告訴您1 GB的位置。

相關問題