調用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);
看似簡單,卻花了我近半個月的時間才找到緣由。
相關文章
相關標籤/搜索