Memory management 使用rapidXML解析多个文件(一个接一个)以使用更少的内存

Memory management 使用rapidXML解析多个文件(一个接一个)以使用更少的内存,memory-management,xml-parsing,rapidxml,Memory Management,Xml Parsing,Rapidxml,我需要读取一个大的XML文件(~5.4GB)。我注意到,使用rapidXML解析文件使用的RAM大约是磁盘上文件大小的6倍(因此解析200 MB文件需要~1.2 GB的RAM,而解析5.4 GB文件需要~32.4 GB的RAM!)。为了避免交换,我决定将文件分割成更小的块,并逐个读取这些块(使用库中的“xml分割”工具)。我可以正确地读取和解析XML文件 问题:当我到达第一个文件的末尾时,我可以成功打开第二个文件,但是第一个文件仍然使用内存,即使我清除rapidxml::document和/或删

我需要读取一个大的XML文件(~5.4GB)。我注意到,使用rapidXML解析文件使用的RAM大约是磁盘上文件大小的6倍(因此解析200 MB文件需要~1.2 GB的RAM,而解析5.4 GB文件需要~32.4 GB的RAM!)。为了避免交换,我决定将文件分割成更小的块,并逐个读取这些块(使用库中的“xml分割”工具)。我可以正确地读取和解析XML文件

问题:当我到达第一个文件的末尾时,我可以成功打开第二个文件,但是第一个文件仍然使用内存,即使我清除
rapidxml::document
和/或删除
rapidxml::file
。以下是头文件:

//*1st code snippet*
//.h file
#include "rapidxml_utils.hpp"        //Implicitly includes 'rapidxml.hpp'
...
private:
  std::basic_ifstream<char> inStream;
  rapidxml::file<>* sumoXmlFile;
  rapidxml::xml_document<> doc;
  uint16_t fcdFileIndex;               //initialized at 0
...
问题是(我认为)在“清理”时(在前面的代码片段中标记为“不确定”的行)。我尝试了几种组合
clear()
delete
,调用
内存池
析构函数。我试过的任何东西都不能释放记忆。我还使用直接打开了XML文件

sumoXmlFile = new rapidxml::file<>(fileName.c_str()); //see 2nd code snippet
sumoXmlFile=new-rapidxml::file(fileName.c_str())//请参阅第二段代码片段
而不是手动创建
ifstream

总结一下,当我打开第一个XML文件时,它成功加载,并使用了一些RAM。完成后,我尝试清理/删除/清除内存池(未成功),并打开第二个文件(成功)。此时,第一个和第二个文件使用内存。解析第二个文件可以正常工作(即使是第三个、第四个,等等),但是RAM在某个时候会非常满

(最后)我的问题:释放第一个文件使用的内存时,我是否做错了什么?是否可以释放使用的内存,然后读取下一个文件?如果需要,我不介意在这个过程中销毁XML文件

(为了完整性:这段代码实际上是一个模拟,XML文件是由生成的。我确信XML文件没有错误。)


感谢您提供的任何帮助或提示

我通过使用Python从XML文件中提取有用的信息来解决这个问题。然后脚本创建一个文件,在OMNeT(C++)中使用
std::istream

逐行读取该文件,我看不出有什么问题。就我个人而言,我会将xmldoc、文件和ifstream封装在一个单独的对象中,然后为每个文件重新删除和构建,而不是试图清除和重用这些对象,但我不希望这能解决您的问题。你是如何测量记忆使用的?嗯。。。我可以试着把所有东西都包在一个物体里,看看它能做什么。我使用系统监视器(更准确地说是KDE的KSysGuard)。在读取下一个XML文件之前,我暂停了模拟(我每1000秒剪切一次文件,这样我就知道它是什么时候),然后一步一步地继续模拟:我看到RAM使用量从~1.2 GB跃升到~3.0 GB。更新:将解析器包装在专用对象中没有帮助:调用析构函数后内存不会被释放:/
//*3rd code snippet*
void update()
{
  //Read next tag
  rapidxml::xml_node<>* node = doc.first_node("timestep");

  //If no 'timestep' tags are left, clean and parse the next file.
  if(!node)
  {
    doc.clear();         //**not sure**
    delete sumoXmlFile;  //**not sure**
    inStream.close();    //**not sure**

    if(parseNextFile())  //See 2nd code snippet
      node = doc.first_node("timestep");
    else
      return;
  }

  //read the children nodes of the current 'timestep'
  for(rapidxml::xml_node<>* veh = node->first_node(); veh; veh = node->first_node())
  {
    ...
    //read some attributes using 'veh->first_attribute("...")'
    ...

    node->remove_first_node();
  }

  doc.remove_first_node();
}
sumoXmlFile = new rapidxml::file<>(fileName.c_str()); //see 2nd code snippet