Утечка памяти с XmlDocument () - PullRequest
3 голосов
/ 30 июля 2011

Я считаю, что у меня есть утечка памяти с некоторым моим кодом, который использует класс XmlDocument.

Моя программа работает на устройстве Windows 6.1.4 (C #) и читает из базы данных на другом сервере, чтобы увидеть,любые программы, установленные на устройстве, должны быть удалены, а затем считаны из XmlDocument, чтобы получить имена программ, которые можно удалить.Затем программа сопоставляет списки и, при необходимости, удаляет их.Этот процесс зацикливается бесконечно и работает в фоновом режиме, но я замечаю, что память медленно ползет со временем, и программа в конечном итоге ловит OutOfMemoryException.

Если я закомментирую все и ничего не сделаю в цикле, память останется примерно на 2 МБ.Если я оставлю все, кроме следующего кода, закомментированного, то использование памяти будет увеличиваться на 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, поскольку System.Configuration не существует.в CF.

Ответы [ 4 ]

2 голосов
/ 04 декабря 2012

У меня была похожая проблема при переборе многих ~ 100 МБ 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 из памяти

0 голосов
/ 30 июля 2011

Вы можете изменить тип cmdStr на StringBuilder.Поскольку строка неизменна, она копируется каждый раз, когда вы добавляете что-либо в строку.

0 голосов
/ 04 августа 2011

Похоже, что ответ на этот вопрос заключается в том, чтобы сделать это изначально, используя DMProcessConfigXML().Использование этого метода не приводит к утечке памяти.Так что внутри оболочки должно быть что-то, что не высвобождает свои ресурсы должным образом.

0 голосов
/ 30 июля 2011

В коде, который вы показываете, cmdStr становится все больше и больше, но я не вижу, чтобы с ним что-либо происходило ... так что это может привести к бесконечному росту потребления памяти и к OutOfMemory-Exception ...

...