我从 C++ 中的 HDF5 代码中看到了奇怪的行为(使用 C 接口)。它最大化了我系统上的 RAM 使用量,但似乎继续运行良好。我不确定它停止分配更多 RAM 的点是否是巧合,或者是否预期某些缓冲区或某些缓冲区的内部行为会这样做。无论如何,问题是如果其他一些应用程序想要使用一些 RAM,那么它就不能,整个系统开始颠簸并锁定。
我运行代码valgrind --tool=massif
并massif-visualizer
尝试查看发生了什么,并得到以下输出:
查看典型快照中的调用链(显示在图像中),看起来它发生在我的一个函数中,当我遍历 HDF5 文件中的一个组以识别它的所有数据集时,它op_func
被重复调用H5Literate
包含。
但是这个函数甚至没有读取或写入任何重要的数据!它所做的只是H5Oget_info_by_name
重复调用以查询数据集名称!所以我不明白为什么这会消耗我所有的 RAM。如果我在做一些愚蠢的事情,这里是重复调用的函数的代码:
inline herr_t op_func (hid_t loc_id, const char *name_in, const H5L_info_t *,
void *operator_data)
{
herr_t return_val = 0;
H5O_info_t infobuf;
std::vector<std::string> &od = *static_cast<std::vector<std::string> *> (operator_data);
std::string name(name_in);
H5Oget_info_by_name (loc_id, name.c_str(), &infobuf, H5P_DEFAULT);
switch (infobuf.type)
{
case H5O_TYPE_GROUP:
{
break;
}
case H5O_TYPE_DATASET:
{
std::string str(name);
if (name.find("_isvalid") == std::string::npos)
od.push_back(std::string(name));
break;
}
case H5O_TYPE_NAMED_DATATYPE:
break;
default:
break;
}
return return_val;
}
如您所见,它非常简单,我只是收集名称并将它们推送到字符串向量上。它可能会使用一些更好的错误检查,但除了这个 RAM 问题之外,它似乎工作得很好。
我在做一些愚蠢的事情来导致内存泄漏吗?还是 HDF5 在其内部缓冲方面真的很激进,并且缓冲的信息比我意识到的要多?也许我只需要告诉它清除一些缓冲区或进行垃圾收集或其他什么?