调用Xerces C++ XML解析库引发的内存泄漏

内存泄漏一直是个很头疼的问题。这类bug的root cause一般都很难找,特别是当代码行数达到数十万行以上的时候。最近帮同事解决了一个此类内存泄漏的问题,缘由是使用Xerces XML库不当所引发的。node

程序在长时间运行时内存不停的在涨。反复测试后,发现只有在调用add/remove操做时内存会增加。而后进一步定位。把除了add/remove函数以外的能删的都删掉。但内存仍是在长。调试的具体过程就不细说了,最后仍是靠一个小case和google解决了问题。app

精简后的伪代码:ide

  
  
  
  
  1. xercesc::DOMElement* createDOM(MemBufInputSource source)   
  2. {   
  3.     XercesDOMParser parser;   
  4.     xercesc::DOMElement* doc ;   
  5.     …   
  6.     parser.parse(source);   
  7.     doc = parser.adoptDocument();   
  8.     …   
  9.     return doc;  
  10. }  
  11.  
  12. void init()   
  13. {   
  14.     DOMElement* _workingXercesConfig = createDOM(src1);  
  15. }  
  16.  
  17. void add()   
  18. {   
  19.     DOMElement* xercesConfig = createDOM(src2);   
  20.     DOMElement* xercesDuplicate = dynamic_cast<DOMElement*>(_workingXercesConfig->cloneNode(true));   
  21.     DOMNode *node = xercesDuplicate->getOwnerDocument()->importNode(xercesConfig, true);   
  22.     xercesConfig->getOwnerDocument()->release();   
  23.     _workingXercesConfig->release();   
  24.     _workingXercesConfig = xercesDuplicate;   
  25.     …  
看似一切都已经被释放了,但问题的缘由出在importNode()上。importNode在把新的Element导入进来的同时,会把相应的metadata及数据都导入,并挂在这颗DOM树上。仅仅调用_workingXercesConfig-&gt;release();不会把这部分数据删除。也就是说要释放这块内存,必需要把整棵DOM树释放并重建。
     
     
     
     
  1. _workingXercesConfig->getOwnerDocument()->release();
  2. DOMElement* _configXerces = createDOM(src1);
看似简单,却花了我近半个月的时间才找到缘由。