移动窗口时 C++/WinApi 内存使用率上升

Posted

技术标签:

【中文标题】移动窗口时 C++/WinApi 内存使用率上升【英文标题】:C++/WinApi Memory Usage rising when moving window 【发布时间】:2018-11-24 15:41:06 【问题描述】:

所以我正在玩我的测试应用程序,发现当我将窗口移动到屏幕边缘时,内存使用量正在上升。

同样在 19mb 内存使用时,字体消失并且应用程序出现错误。

但是,当窗口不接触屏幕边缘时,不会发生这种情况。

这是我的youtube video,表明我的意思。

我认为我的代码效率不高。

绘制文字代码:

void drawText(LPCWSTR text, LPCWSTR fontName,int fontSize, int x, int y, HDC hdc) 

    //Creat font from name and size

    HFONT font =  CreateFont(
        fontSize,
        0,
        0,
        0,
        FW_NORMAL, 
        FALSE,
        FALSE,
        FALSE,
        ANSI_CHARSET,
        OUT_CHARACTER_PRECIS,
        CLIP_CHARACTER_PRECIS,
        CLEARTYPE_QUALITY,
        DEFAULT_PITCH,
        fontName);

    //Change Current Font

    HFONT oldFont = (HFONT) SelectObject(hdc, font);

    //Draw Text
    TextOut(hdc,
        x,
        y,
        text,
        wcslen(text));

    //Set back old font
    SelectObject(hdc, oldFont);

实施:

   case WM_PAINT:
      PAINTSTRUCT ps;
      HDC hdc = BeginPaint(hwnd, &ps);

      int y = 10;

      drawText(L"Hey, im Roboto", L"Roboto", 50, 10, y, hdc);
      y += 80;
      drawText(L"Hey, im Arial", L"Arial",50, 10, y, hdc);
      y += 80;
      drawText(L"Hey, im Lucida Grande", L"Lucida Grande", 50, 10, y, hdc);

      EndPaint(hwnd, &ps);

      break;

【问题讨论】:

您好像忘记删除字体了。 感谢 DeleteObject(font);确实解决了问题。但我想知道内存上升的原因。 您没有在使用后释放资源。为什么您希望内存使用量不会增加? 【参考方案1】:

这似乎是内存泄漏的常见情况。根据MSDN:

当系统或其他应用程序请求绘制应用程序窗口的一部分时发送 WM_PAINT 消息。

这意味着每次系统要请求程序重绘窗口时,WM_PAINT 消息都会发送到您的 WindowProc 回调函数。如果您使用鼠标移动窗口,则每次窗口改变位置时都会重新绘制!你可以试试Control Spy v2.0 看看确实是这样。

无论哪种方式,每次出于任何原因需要重绘窗口时,您都会创建一种新字体。比如当它被移动一点点时。这样,内存使用量将快速增加。而如果在将字体应用到文本后使用DeleteObject 删除字体,它会从内存中释放字体,因此不会明显增加实际内存。

【讨论】:

这不仅仅是内存泄漏。这是资源泄漏。从不同的内存分配不同的对象。虽然进程堆通常大量可用,但 GDI 对象(如字体)are allocated from a heap far more limited 的大小。

以上是关于移动窗口时 C++/WinApi 内存使用率上升的主要内容,如果未能解决你的问题,请参考以下文章

使用 gdi 在 winapi 窗口中的运行时更新颜色

C#。 WinApi。在窗口上绘制

C# WinAPI 从静态检查窗口文本

如何在c ++ winapi中获取活动文件资源管理器窗口的路径

c ++ Opengl,Win内存泄漏

C++ 对接窗口