【问题标题】:Why HBITMAP use so little memory?为什么 HBITMAP 使用这么少的内存?
【发布时间】:2010-01-24 14:27:34
【问题描述】:

我遇到了一个有趣的问题:

  1. 通过 libjpeg 将大 (4500x6000) jpeg 加载到内存 (RGBRGBRGB....) 中(大约需要 200M 内存)
  2. CreateDIBitmap() 从数据中创建 HBITMAP
  3. 释放使用的内存

现在我发现进程只使用了 5M 内存。我想知道 HBITMAP 的数据在哪里。 (我禁用页面文件)


更新:

我写了这样的代码进行测试:

    // initilise 
    BITMAP bitmap;
    BITMAPINFO info;
    // ....
    void *data = NULL;
    HDC hdc = ::GetDC(NULL);
    HBITMAP hBitmap = ::CreateDIBSection(hdc, &info, DIB_RGB_COLORS, &data, NULL, 0);
    ::ReleaseDC(NULL, hdc);

    if (hBitmap) {
        ::GetObject(m_hBitmap, sizeof(bitmap), &bitmap);
    }

那么数据是0x2d0000(肯定在用户空间),bitmap.bmBits也是0x2d0000。所以我确保 CreateDIBSection 将用户空间内存用于位图。

【问题讨论】:

  • 你怎么知道它使用了多少内存?如果您只是查看任务管理器,那并不总是准确的衡量标准。

标签: winapi bitmapdata


【解决方案1】:

这个测试怎么样。在循环中创建 HBITMAP。计算理论上使用的字节数(基于视频卡的位深度)。

在 HBITMAP 开始失败之前,您可以分配多少字节? (或者,或者,直到您确实开始看到对内存的影响)。

DDB 由设备驱动程序管理。因此,它们倾向于存储在以下两个位置之一:- 内核模式分页池或视频卡内存本身。这两者都不会反映在任何进程内存计数中。 理论上,设备驱动程序可以为位图分配系统内存存储,并在需要时将它们移动到 vram ......但一些视频卡驱动程序认为视频内存应该足够并且简单地分配卡上的所有 HBITMAP。这意味着您在 2Gb 标记(如果它们分配在内核分页池中;取决于可用的内存并假设 32 位 Windows 版本)或 256Mb 标记(或视频卡有多少内存)处的 HBITMAP 空间不足。

该讨论涵盖了设备相关位图。

DIBSection 是一种特殊情况,因为它们分配在可从内核模式访问的内存中,但在用户空间中可用。因此,任何使用大量位图的应用程序都可能应该在可能的情况下使用 DIBSections,因为应该很少有机会耗尽系统空间来存储 DDB。 我怀疑一个系统范围内的 DIBSections 值仍然高达 2Gb(在 32 位 Windows 版本上),因为在需要访问视频设备驱动程序的内核模式下没有“当前进程”的概念。

【讨论】:

  • 我认为你是对的,也许HBITMAP的数据存储在内核模式(或显卡)中,所以我只能在任务管理器或进程资源管理器中看到很少的内存使用情况(来自sysinternals) .但我不知道如何验证这一点。
  • 是的,你是对的。如果我使用 CreateDIBSection,数据存储在用户空间,而不是内核。谢谢你:)
  • CreateDIBSection 如果我对内存映射和内核模式的理解是正确的,应该用完内核和用户空间。
猜你喜欢
  • 2013-06-06
  • 2012-06-28
  • 1970-01-01
  • 1970-01-01
  • 2016-05-05
  • 2016-12-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-23
相关资源
最近更新 更多