XmlDocument()内存泄漏

时间:2011-07-29 20:57:39

标签: c# memory-leaks windows-mobile xmldocument windows-mobile-6.1

我相信我的内存泄漏了一些使用XmlDocument类的代码。

我的程序在Windows 6.1.4设备(C#)上运行,并从另一台服务器上的数据库读取,以查看是否需要卸载设备上安装的任何程序,然后从XmlDocument读取以获取程序的名称这是可以卸载的。然后,程序会相应地匹配列表并卸载,如有必要。这个过程无限循环并在后台运行,但我注意到的是内存随着时间的推移慢慢爬升,程序最终会捕获OutOfMemoryException

如果我在循环中注释掉所有内容并且什么都不做,那么内存一直保持在2MB左右。如果我将所有内容都删除,但下面的代码被注释掉了,那么内存使用量每分钟都会持续增加.05兆字节。这些结果是让循环睡眠1秒钟。常规睡眠速度约为10分钟。关于什么可能导致泄漏以及它是否与XmlDocument类有关的任何想法?

foreach (string programName in uninstallPrograms)
{
    XmlDocument xmlDoc1 = new XmlDocument();
    xmlDoc1.LoadXml("<wap-provisioningdoc>" +
          "  <characteristic type=\"UnInstall\">" +
          "    <characteristic type=\"" + programName + "\">" +
          "     <parm name=\"uninstall\" value=\"1\"/>" +
          "    </characteristic>" +
          "  </characteristic>" +
          "</wap-provisioningdoc>");

    xmlDoc1 = ConfigurationManager.ProcessConfiguration(xmlDoc1, true);

    cmdStr += "DELETE FROM DEVICE_APPS WHERE ID = " + deviceAppIDList[count++] + "; ";

    xmlDoc1 = null;
}

// Check for pre-installed apps to uninstall
count = 0;

XmlDocument xmlDoc2 = new XmlDocument();

xmlDoc2.LoadXml("<wap-provisioningdoc><characteristic-query type=\"UnInstall\"/>" +
        "</wap-provisioningdoc>");

/**** The line below seems to be the cause of the memory leak ****/
//xmlDoc2 = ConfigurationManager.ProcessConfiguration(xmlDoc2, true);

XmlNodeList xmlNodeList = xmlDoc2.SelectNodes("wap-provisioningdoc/" +
        "characteristic[@type='UnInstall']/characteristic/@type");

xmlDoc2 = null;

cmdStr最终会被使用,并在循环结束时设置为string.Empty。起初我的代码中没有xmlDoc = null;,但无论如何都没有帮助。我已经尝试在循环结束时添加GC.Collect();,这似乎有助于减缓泄漏,但它并没有完全修复它。另外,我认为使用它并不是一个好习惯。

编辑:所以它似乎是我在上面的代码中注释掉的具有内存泄漏的ConfigurationManager行。一旦我注释掉那行代码,内存泄漏就会停止。当我取消注释这一行时,它会重新开始。在调用ProcessConfiguration以释放内存后,我需要做些什么吗?

此外,我正在使用ConfigurationManager运行时版本1.1.4322的Microsoft.WindowsMo​​bile.Configuration命名空间,因为CF中不存在System.Configuration。

5 个答案:

答案 0 :(得分:2)

我在迭代许多~100 MB xml文件时遇到了类似的问题。我尝试了上面写的所有内容,但没有一个帮助过。最后,我将xml处理分离为一个单独的虚函数,然后垃圾收集工作正常。我做了这样的事情:

function f()
{
    FileInfo[] rgFiles = di.GetFiles("*.xml.gz", SearchOption.TopDirectoryOnly);
    //process all *.xml.gz files in folder
    foreach (FileInfo fi in rgFiles)
    {
        forGC(fi);
    }
}

功能forGC完成了所有工作。现在可以理解垃圾收集何时可以从内存中删除xml

答案 1 :(得分:0)

在你展示的代码中,cmdStr变得越来越大但是我没有看到任何事情发生过......所以这会导致你的记忆消耗无限增长并导致OutOfMemory-Exception ......

答案 2 :(得分:0)

您可以将cmdStr的类型更改为StringBuilder。 因为string是不可变的,所以每当你向字符串追加一些东西时它就会被复制。

答案 3 :(得分:0)

看起来答案是使用DMProcessConfigXML()本地执行此操作。使用此方法不会导致内存泄漏。因此,包装器中必须存在未正确释放其资源的内容。

答案 4 :(得分:0)

重复的问题 https://stackoverflow.com/questions/42226993/how-to-dispose-xmldocument 寻找GyörgyKőszeg答案。

using语句将调用Dispose清理资源。 XmlDocument不是IDisposposable,但FileStream是。