2017-08-13 291 views
0

我每40ms調用以下void function()函數,我發現內存消耗量穩步增加。消費起初並不明顯,但幾天之後,消費量很大。任何人都可以幫助解釋這段代碼有什麼問題。這是一個線程問題還是std::move問題,導致內存泄漏。C++程序潛在的內存泄漏

void do_task(const std::vector<int>& tmp) 
{ 
    // do some work here 
} 

void function() 
{ 
    std::vector<std::thread> task; 
    std::vector<int> tmp1, tmp2; 

    GetTempValue(tmp1); 
    GetTempValue(tmp2); 

    task.push_back(std::thread(do_task, std::move(tmp1))); 
    task.push_back(std::thread(do_task, std::move(tmp2))); 

    tmp1.clear(); 
    tmp2.clear(); 

    UpdateTempValue(tmp1); 
    UpdateTempValue(tmp2); 

    task.push_back(std::thread(do_task, std::move(tmp1))); 
    task.push_back(std::thread(do_task, std::move(tmp2))); 

    tmp1.clear(); 
    tmp2.clear(); 

    for(int i=0; i<task.size(); i++) 
    { 
     task[i].join(); 
    } 
} 
+0

我不假設您是通過Valgrind發送的?無論如何,如果移動語義在做他們的工作,那些清除就毫無意義。出於好奇,請用您的平臺工具鏈信息更新您的問題,最好是[mcve](https://stackoverflow.com/help/mcve)。 – WhozCraig

+1

@rxu。上面的代碼不存在數據競爭問題。矢量tmp1和tmp2處理得相當正確。除了clear()的調用是多餘的。 –

+0

對不起,噪音:) –

回答

1

傳遞對線程的引用是一個很大的禁忌。或至少有一個等待發生的錯誤...

你應該嘗試重新定義做任務接受一個std ::向量的值。是不是通過調用std :: move將它們傳遞給線程來嘗試做什麼?

變化do_task來定義:

void do_task(std::vector<int> tmp); 

我做了一些快速計算。如果由函數()開始的線程泄漏,每40ms啓動4個線程,則泄漏率應該超過1.4MB /小時。如果你的泄漏小於這個值,你應該開始尋找代碼中的其他地方。

在任何情況下,每秒啓動100個線程的效率並不高。在創建線程時,大部分計算能力都會丟失。你考慮過其他選擇嗎?

讓4個線程運行無限循環,並將工作排隊等待將會更有效率,減少對操作系統的徵稅,並減少無法控制的泄漏。

+0

這是有道理的。我每40ms啓動6個線程,do_task是一個光學字符識別功能。那爲什麼會泄漏? – Johnnylin

+0

識別部分可能泄漏你正在使用tesseract? – Hakes

+0

@Heak ocr程序沒有泄漏,傳遞給do_task的向量只是一個類似於目的的查找表。 – Johnnylin