You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

Arch Linux(Sway)下Nvidia显卡OpenGL项目内存泄漏求助

问题:Arch+Sway下Nvidia设备OpenGL开发内存泄漏排查

迁移至Arch Linux(Sway桌面环境)开展C++ OpenGL开发时遇到内存泄漏问题:项目在AMD核显笔记本上运行正常,但在AMD处理器+Nvidia独显设备上,无论使用Nvidia闭源驱动还是nouveau驱动,均出现内存泄漏。以下是LeakSanitizer检测日志及测试代码,求排查方向:

LeakSanitizer检测日志

=================================================================
==1560==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 139200 byte(s) in 100 object(s) allocated from:
    #0 0x7fd803720cb5 in malloc (/usr/lib/libasan.so.8+0x120cb5) (BuildId: 0b96d08695bbce2da9d4770c29ad2e72fb536f47)
    #1 0x7bd7fddf1e31  (/usr/lib/libnvidia-glcore.so.590.48.01+0x9f1e31) (BuildId: 624c9fc17b00e85a78557f9c9b7e4a26f69eb02d)

Indirect leak of 140000 byte(s) in 50 object(s) allocated from:
    #0 0x7fd8037205dd in calloc (/usr/lib/libasan.so.8+0x1205dd) (BuildId: 0b96d08695bbce2da9d4770c29ad2e72fb536f47)
    #1 0x7bd7fddf20ed  (/usr/lib/libnvidia-glcore.so.590.48.01+0x9f20ed) (BuildId: 624c9fc17b00e85a78557f9c9b7e4a26f69eb02d)

SUMMARY: AddressSanitizer: 279200 byte(s) leaked in 150 allocation(s).

测试代码

glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // 👈 隐藏窗口
glfwInitHint(GLFW_PLATFORM, GLFW_PLATFORM_X11);
if (!glfwInit()) {
    std::cerr << "Failed to initialize GLFW!" << std::endl;
    throw new std::runtime_error("Failed to initialize GLFW!");
}
for (int i = 0; i < 50; i++) {
    // 不存储窗口,仅创建后销毁
    GLFWwindow *temp_window = glfwCreateWindow(800, 600, "Temp", nullptr, nullptr);

    glfwMakeContextCurrent(temp_window);
    int version = gladLoadGL(glfwGetProcAddress);

    glfwDestroyWindow(temp_window);
    // 可选:强制处理Wayland事件
    glfwPollEvents();

    // 打印进度
    if ((i + 1) % 10 == 0) {
        std::cout << "Created/destroyed " << (i + 1) << " windows" << std::endl;
        // 此处可检查内存占用
    }
}
glfwTerminate();

排查方向

  • 补全上下文清理步骤:销毁窗口前必须解除当前上下文绑定,否则Nvidia驱动可能持有上下文相关内存无法释放。修改循环内代码:
    glfwMakeContextCurrent(temp_window);
    int version = gladLoadGL(glfwGetProcAddress);
    
    // 新增:解除上下文绑定
    glfwMakeContextCurrent(nullptr);
    glfwDestroyWindow(temp_window);
    
  • 排查驱动问题:泄漏来源为libnvidia-glcore.so内部分配,属于驱动层面问题:
    • 尝试更新Nvidia闭源驱动至最新稳定版,或回退至旧版兼容驱动
    • 检查nouveau驱动的内核模块参数,是否存在影响内存回收的配置
  • 验证Wayland/X11兼容性:Sway是Wayland compositor,即使指定X11平台也可能存在XWayland适配问题:
    • 移除glfwInitHint(GLFW_PLATFORM, GLFW_PLATFORM_X11),让GLFW自动适配Wayland后测试
    • 在纯X11桌面环境(如Xfce)下运行代码,确认泄漏是否依然存在
  • 确认是否为误报:部分驱动会在进程退出时统一释放内存,LeakSanitizer可能误判:
    • valgrind重新检测,对比结果
    • htop实时监控进程内存占用,确认是否真的持续增长
  • 检查Glad初始化资源:部分Glad版本可能需要显式清理初始化时分配的资源,查阅Glad文档确认是否有未调用的清理函数

内容的提问来源于stack exchange,提问作者Filip Cacic

火山引擎 最新活动