【发布时间】:2019-09-01 09:26:11
【问题描述】:
在将问题规模扩大到我交给一个自编码程序的过程中,我开始遇到 Linux 的 OOM 杀手。 Valgrind(在 CPU 上运行时)和 cuda-memcheck(在 GPU 上运行时)都不会报告任何内存泄漏。在遍历内部循环时,内存使用量不断扩大,而我在此循环结束时明确清除了保存最大数据块的向量。如何确保这种内存占用消失?
已执行内存泄漏检查,所有内存泄漏均已修复。尽管如此,内存不足错误仍会继续终止程序(通过 OOM Killer)。手动监控内存消耗显示内存利用率增加,即使在明确清除包含数据的向量之后也是如此。
要知道的关键是有三个嵌套循环,一个外部包含手头的子问题。中间循环循环蒙特卡洛试验,内部循环运行试验内部所需的一些顺序过程。伪代码如下:
std::vector<object*> sub_problems;
sub_problems.push_back(retrieved_subproblem_from_database);
for(int sub_problem_index = 0; sub_problem_index < sub_problems.size(); ++sub_problem_index){
std::vector< std::vector<float> > mc_results(100000, std::vector<float>(5, 0.0));
for(int mc_trial = 0; mc_trial < 100000; ++mc_trial){
for(int sequential_process_index = 0; sequential_process_index < 5; ++sequential_process_index){
mc_results[mc_trial][sequential_process_index] = specific_result;
}
}
sub_problems[sub_problem_index]->storeResultsInObject(mc_results);
// Do some other things
sub_problems[sub_problem_index]->deleteMCResults();
}
deleteMCResults 如下所示:
bool deleteMCResults() {
for (int i = 0; i < asset_values.size(); ++i){
object_mc_results[i].clear();
object_mc_results[i].shrink_to_fit();
}
object_mc_results.clear();
object_mc_results.shrink_to_fit();
return true;
}
如何确保内存消耗完全依赖于中间和内循环而不是外循环?第二个、第三个和第四个等理论上可以使用与第一次迭代完全相同的内存空间/地址。
【问题讨论】:
-
std::vector<object*> sub_problems;- 这些是new'ed 对象吗? IE。每个object的堆分配?因为这会带来每次分配的开销。 sn-p 没有显示这是否是问题;一些大物体不是问题,但许多小物体是问题。 -
请注意,
shrink_to_fit不需要这样做。对嵌套向量做任何事情都没有意义,因为它们在循环后被销毁。
标签: c++ linux memory-management out-of-memory