0

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

  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 将用户空间内存用于位图。

4

1 回答 1

2

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

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

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

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

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

于 2010-01-24T19:50:38.017 回答