2017-08-13 112 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