【发布时间】:2020-08-10 14:21:40
【问题描述】:
我正在使用 Qt 和 OpenGL 开发 3D 编辑器,但似乎无缘无故地遇到了严重的“内存泄漏”。我已将问题隔离到一个类中,如下所示:
template <size_t SIZE>
class GlVoxelChunk {
private:
gl::FunctionsX *glFuncs; // unmanaged pointer, points to a global variable
Color data[SIZE * SIZE * SIZE];
Vec3i pos;
GLuint glTexture = 0;
std::vector<GLfloat> vertices;
std::vector<GLbyte> colors;
std::vector<GLuint> elements;
...
}
// all chunks are stored like this:
std::map<Vec3i, GlVoxelChunk<16>>
这里的两个大内存猪是 3D 数组和包含上传到 GL 的数据的向量。
当加载一个大型模型并用它填充这些块时,内存使用量会上升到大约 3GB。当删除模型并因此再次删除这些块时,它不会出现任何问题。我的第一个猜测是这些块永远不会被破坏,但事实并非如此。我:
- instance对chunk进行计数,删除模型后计数回0
- 使用实例计数对象创建了另一个向量,这些对象也都被正确清除
- 使用 memgrind 运行我的应用程序以检测任何丢失的内存,但什么也没找到
- 检查是否使用 gdb 调用了析构函数并且它们都调用了
我自己什至不手动管理任何内存,这些块都存储在std::map 中。我可以肯定地说这些向量是罪魁祸首,因为当我根本不填充它们时,删除 3D 对象时内存使用量会下降到接近于零。更奇怪的是,如果我填充它们,没有内存被释放,甚至这些 3D 数组也没有被释放。
在这一点上,我不知道该怎么办。如果 Memgrind 甚至无法检测到 3GB 内存泄漏,它就毫无用处。我还能做什么?
【问题讨论】:
-
你如何看待或衡量它没有被释放?
-
如果 memgrind 没有检测到内存泄漏,这表明内存可能没有泄漏;相反,它可能已被分配并且从未被释放,但由于程序中的其他地方仍然存在指向已分配内存的指针,因此它不能算作泄漏,因为程序仍然有能力释放它。 (我最常在以下情况下看到这种行为,例如程序不断向向量或其他数据结构添加新项目,但忘记清除向量或删除项目,以便向量无限期地变得越来越大)
-
@RoQuOTriX KSysGuard 和 htop 中显示的内存使用量为 3GB。
-
您是否使用操作系统实用程序来告诉您每个应用程序使用了多少内存?如果是这样,释放应用程序内部的内存并不一定会将其返回给操作系统。因此,即使没有泄漏,操作系统报告的内存量也不一定会下降。释放的内存可在应用程序中重复使用。
-
注意:
shrink_to_fit是一个礼貌的请求,如果程序看到不收缩的好处,可以忽略它。
标签: c++ opengl memory memory-leaks