我相信我有一些使用XmlDocument类的代码内存泄漏。
我的程序在Windows 6.1.4设备(c#)上运行,并从另一台服务器上的数据库读取,以查看设备上安装的任何程序是否需要卸载,然后从XmlDocument读取以获得可卸载程序的名称。然后,程序匹配列表并根据需要卸载。这个进程是无限循环的,在后台运行,但我注意到的是,随着时间的推移,内存慢慢增加,程序最终捕获了一个OutOfMemoryException
。
如果我注释掉所有内容并且在循环中不做任何事情,则内存始终保持在2MB左右。如果我将除以下代码外的所有代码都注释掉,那么内存使用量每分钟增加0.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以释放内存后,我需要做些什么吗?
此外,我使用Microsoft.WindowsMobile.Configuration命名空间的ConfigurationManager运行时版本1.1.4322自系统。CF中不存在配置
我在迭代许多~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
在代码中,你显示cmdStr越来越大,但我没有看到任何事情发生与它…所以这将导致内存消耗无限增长,并导致OutOfMemory-Exception…
您可以将cmdStr的类型更改为StringBuilder。因为字符串是不可变的每次你往字符串后面添加内容时它都会被复制
看起来这个问题的答案是使用DMProcessConfigXML()
本地完成它。使用此方法不会导致内存泄漏。因此,包装器中一定有什么东西没有正确释放其资源。
重复问题https://stackoverflow.com/questions/42226993/how-to-dispose-xmldocument查找György Kőszeg答案
using语句将调用Dispose来清理资源。XmlDocument不是IDisposable,但FileStream是。