wxGLCanvas调整窗口大小后内存占用过高且无法释放问题求助
问题原因及修复方案
核心问题排查
- 未绑定上下文调用GL函数:你在
Resize方法中直接调用glViewport,所有OpenGL函数执行前必须先调用SetCurrent(*m_context)将对应GL上下文绑定到当前线程。未绑定上下文的GL调用会触发驱动层未定义行为,大部分桌面显卡驱动会为错误调用分配临时处理资源且不会自动回收,频繁触发resize事件时会快速累积内存占用,这是导致内存暴涨到数百MB的核心原因。 - 存在GL资源重复创建风险:你通过
setup变量控制初始化逻辑的执行,如果SetupGraphics执行完成后没有立刻将setup赋值为true,窗口调整大小触发的上百次resize事件会反复执行InitializeGLEW和SetupGraphics,每次创建新的VAO、VBO、着色器等GL资源,这些资源会同时占用显存和系统内存,且不会自动释放。 - 常规内存泄漏:构造函数中
new创建的wxGLContextAttrs对象ctx_attr在GL上下文创建完成后就没有作用,你没有主动释放该对象,虽然该部分内存占比极小,但属于需要修复的泄漏点。
修复代码示例
修复Resize方法
void TriangleCanvas::Resize(wxSizeEvent& event) { event.Skip(); // 绑定上下文后再调用GL函数 if (IsShownOnScreen() && m_context != nullptr) { SetCurrent(*m_context); glViewport(0, 0, event.GetSize().GetX(), event.GetSize().GetY()); } if (!setup) { if (m_context != nullptr) SetCurrent(*m_context); InitializeGLEW(); SetupGraphics(); setup = true; // 必须赋值,避免后续resize重复执行初始化 } // 触发重绘,保证resize后画面同步更新 Refresh(false); }
补充析构资源释放逻辑
TriangleCanvas::~TriangleCanvas() { // 释放GL资源前必须先绑定上下文 SetCurrent(*m_context); glDeleteBuffers(1, &m_vbo); glDeleteBuffers(1, &m_ebo); glDeleteVertexArrays(1, &m_vao); delete shader; // 释放wx层对象 delete m_context; delete ctx_attr; }
额外检查项
- 确认
SetupGraphics中所有GL对象的创建逻辑只执行一次,没有重复创建资源的代码 - 不要删除
OnPaint中的wxPaintDC构造语句,wxWidgets要求所有wxEVT_PAINT事件处理必须构造wxPaintDC对象,否则会导致paint事件循环触发,额外占用CPU和内存
内容的提问来源于stack exchange,提问作者Omar Walid
相关产品推荐
相关产品推荐

