2010-07-14 85 views
0

我遇到過一種情況(在Win32上),std :: ostringstream對象繼續佔用進程內存,即使它是在一系列附加型操作之後表面上被清除掉了。請看看這個C++片段:VS2008中的C++ STL:std :: ostringstream在嚴重分配/清除用法後拋出std :: bad_alloc

int main(void) 
{ 
    std::ostringstream cOutputLogStream; 

    // Random long string 
    std::string sTest = "jkspoiauyeraspfoiusdfsdfekgpweojkgpwoekpokgkpgeopoegwj"; 

    std::string sEmpty = ""; 

    int n = 0; 
    int looper = 0; 

    while (n++ < 100000) 
    { 
     while (looper++ < 45) 
     { 
      cOutputLogStream << s; 
     } 

     cOutputLogStream.str(sEmpty); 
     cOutputLogStream.clear(); 

     // This should give the heap manager a chance to consolidate 
     // fragmented memory blocks 
     Sleep(1); 
    } 
} 

期間內while()循環的執行期間,在任務管理進程的內存使用情況的觀察示出了連續向上的斜坡,並最終變平。但是,這種平衡關閉發生在重複拋出錯誤std :: bad_alloc的同時。這表明堆內存已經耗盡,或者請求的塊大小在連續空間中不可用。

是否有其他人用ostringstream對象體驗過這種泄漏現象,還有哪些其他替代對象可用來代替這種片狀對象?

非常感謝!

回答

2

我看不出這個代碼如何重現問題。活套增加到45後,它應該完成消耗任何內存。

通用診斷是程序很少設法消耗所有可能的可用虛擬內存。它首先會在堆中找到大量連續字節,這些字節足以存儲字符串流緩衝區。它被稱爲地址空間碎片,沒有什麼可以做的。您的Sleep()調用肯定不會有用,整合分配的堆塊需要垃圾收集器。

另一個非常標準的陷阱是使用TaskMgr.exe來診斷內存使用情況。它通常顯示工作集,映射到RAM的虛擬內存量。這通常只是程序消耗的虛擬內存量的一小部分,無法真正衡量您的程序消耗了多少虛擬內存。或者告訴你關於地址空間碎片的任何事情。

SysInternals的VMMap實用程序可以顯示您的程序如何使用虛擬內存。

相關問題