c++ - ecCodes(grib 阅读库)不会释放内存
问题描述
我在我的项目中使用ecCodes 库,我遇到了一个问题,即在读取文件之间没有释放内存。
代表问题的最小示例是这样的(并且基本上是这两个库 API 使用示例 [ 1 ](https://confluence.ecmwf.int/display/ECC/grib_get_keys)[2]的组合:
#include <string>
#include <vector>
#include <iostream>
#include "eccodes.h"
int main() {
std::string filenames[] = {"../data/era5_model.grib", "../data/era5_model2.grib", "../data/era5_model3.grib",
"../data/era5_model4.grib"};
std::vector<long> vec = {};
for (auto & filename : filenames) {
FILE* f = fopen(filename.c_str(), "r");
int err = 0;
codes_handle* h;
while ((h = codes_handle_new_from_file(nullptr, f, PRODUCT_GRIB, &err)) != nullptr) {
long k1 = 0;
err = codes_get_long(h, "level", &k1);
vec.push_back(k1);
}
codes_handle_delete(h);
fclose(f);
}
std::cout << vec[52];
return 0;
}
在示例中,程序读取 4 个相同的 ERA5 文件,每个文件大小为 1.5GB。在打开新文件之前,使用codes_handle_delete() 和fclose() 关闭前一个文件。因此,预期的行为是内存使用量保持在 1.5GB 左右。然而,实际上内存使用量稳步增加到大约 6.5GB,并在程序关闭时被释放(见下面的截图)。
这个特定的示例已经使用 CMake(发布配置)在 CLion 上运行,但问题发生在所有其他配置以及我的其他使用 FFI 调用 ecCodes 的 Rust 项目中。
该库似乎经过良好测试和支持,因此它似乎不太可能是库错误。因此,这是预期的行为还是我的代码错误?如果是后者,我该如何纠正?
我正在使用安装了 apt 的 Ubuntu 21.04 和 ecCodes 2.20.0
解决方案
所以我联系了图书馆的作者,发现我没有仔细阅读这个例子。
为了让 ecCodes 正确释放内存codes_handle
,应该在每次创建内存时删除它(类似于每次分配内存时应该如何释放内存)。因此在我的示例中codes_handle_delete()
应该在while
循环内:
while ((h = codes_handle_new_from_file(nullptr, f, PRODUCT_GRIB, &err)) != nullptr) {
long k1 = 0;
err = codes_get_long(h, "level", &k1);
vec.push_back(k1);
codes_handle_delete(h);
}
在那之后改变内存使用几乎是不明显的。
推荐阅读
- theorem-proving - Dafny 多组
- python - 将dict转换为pandas数据框,键为column1,值为col2
- java - 如何修复运算符'>'不能应用于'java.lang.String','java.lang.String'
- oracle - 当连接因超时关闭时,Oracle 是否会回滚事务?
- wildcard - 我可以在 info-plist 上为 Bonjour 服务使用通配符吗
- linux - bazelisk proxyconnect tcp: net/http: TLS 握手超时
- .net - javascript 类中的 Dashboard.js
- python - Python按字母顺序排序二维列表不起作用
- reactjs - 在 useEffect 中使用 useRef current 的问题
- raspberry-pi - 使用 JasperE84/root-ro 脚本更改内核 switch_root