Почему HBITMAP использует так мало памяти? - PullRequest
0 голосов
/ 24 января 2010

Я встретил интересный вопрос:

  1. загрузка большого (4500x6000) JPEG в память (RGBRGBRGB ....) с помощью libjpeg (стоимость около 200M памяти)
  2. CreateDIBitmap () для создания HBITMAP из данных
  3. освободить используемую память

Теперь я обнаружил, что процесс использует только 5М памяти. Интересно, где данные 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 использует память пространства пользователя для растрового изображения.

1 Ответ

2 голосов
/ 24 января 2010

Как насчет этого для теста. Создавайте HBITMAP в цикле. Подсчет количества использованных теоретически байтов (в зависимости от разрядности вашей видеокарты).

Сколько байтов HBITMAP можно выделить до того, как они начнут давать сбой? (Или, поочередно, пока вы не начнете видеть влияние на память).

DDB управляются драйверами устройств. Следовательно, они, как правило, хранятся в одном из двух мест: - в выгружаемом пуле режима ядра или в самой памяти видеокарт. И то, и другое не будет отражено ни в одном подсчете памяти процесса. Теоретически драйверы устройств могут выделять системную память для растровых изображений, перемещая их в vram по мере необходимости ... но некоторые драйверы видеокарт считают, что видеопамяти должно быть достаточно, и просто выделяют все HBITMAP на карте. Это означает, что вам не хватает места для HBITMAP либо с отметкой 2 ГБ (если они выделены в выгружаемом пуле ядра; в зависимости от доступного ОЗУ и при условии 32-разрядных версий Windows), либо с отметкой 256 МБ (или сколько памяти у видеокарты).

Это обсуждение охватывало зависимые от устройства растровые изображения.

DIBSections - это особый случай, поскольку они размещаются в памяти, доступной из режима ядра, но доступны в пользовательском пространстве. Таким образом, любое приложение, которое использует большое количество растровых изображений, вероятно, должно использовать, где это возможно, DIBSections, поскольку должно быть гораздо меньше возможностей истощить систему пространства для хранения DDB. Я подозреваю, что для системы по-прежнему существует ограничение DIBSections на уровне 2 Гб (в 32-битных версиях Windows), поскольку отсутствует понятие «текущий процесс» в режиме ядра, к которому драйверы видеоустройств будут нуждаться в доступе.

...