調用Xerces C++ XML解析庫引起的內存泄漏

內存泄漏一直是個很頭疼的問題。這類bug的root cause通常都很難找,特別是當代碼行數達到數十萬行以上的時候。最近幫同事解決了一個此類內存泄漏的問題,原因是使用Xerces XML庫不當所引起的。

程序在長時間運行時內存不停的在漲。反覆測試後,發現只有在調用add/remove操作時內存會增長。然後進一步定位。把除了add/remove函數之外的能刪的都刪掉。但內存還是在長。調試的具體過程就不細說了,最後還是靠一個小case和google解決了問題。

精簡後的僞代碼:

  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);
看似簡單,卻花了我近半個月的時間才找到原因。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章