Защо HBITMAP използва толкова малко памет?

Срещнах интересен въпрос:

  1. заредете голям (4500x6000) jpeg в паметта (RGBRGBRGB....) от libjpeg (струва около 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 използва паметта на потребителското пространство за растерно изображение.


person ddh    schedule 24.01.2010    source източник
comment
Откъде знаеш колко памет използва? Ако просто гледате диспечера на задачите, това не винаги е точен показател.   -  person i_am_jorf    schedule 24.01.2010


Отговори (1)


Какво ще кажете за това за тест. Създавайте HBITMAP в цикъл. Преброяване на броя теоретично използвани байтове (Въз основа на битовата дълбочина на вашата видеокарта).

Колко байта на стойност HBITMAP можете да разпределите, преди да започнат да се провалят? (Или алтернативно, докато не започнете да виждате въздействие върху паметта).

DDB се управляват от драйвери на устройства. Следователно те са склонни да се съхраняват на едно от двете места: - страниран пул в режим на ядрото или в самата памет на видеокартата. И двете няма да бъдат отразени в броя на паметта на процеса. На теория драйверите на устройства могат да разпределят системна памет за съхранение на растерни изображения, премествайки ги във vram, когато и когато е необходимо... но някои драйвери на видеокарти смятат, че видео паметта трябва да е достатъчна и просто разпределят всички HBITMAP на картата. Което означава, че ви липсва място за HBITMAP или на маркировка 2Gb (ако са разпределени в пула на страниците на ядрото; в зависимост от наличната RAM и при допускане на 32-битови издания на Windows), или на маркировка 256Mb (или колкото и памет да има видеокартата).

Тази дискусия обхваща растерни изображения, зависещи от устройството.

DIBSections са специален случай, тъй като са разпределени в памет, достъпна от режим на ядрото, но достъпна в потребителското пространство. Като такова, всяко приложение, което използва много растерни изображения, вероятно трябва да използва DIBSections, където е възможно, тъй като трябва да има много по-малко възможности системата да не разполага с пространство за съхранение на DDB. Подозирам, че човек все още има ограничение за цялата система от DIBSections до 2 Gb (на 32-битови версии на Windows), тъй като няма концепция за „текущ процес“ в режим на ядрото, където драйверите на видео устройствата ще имат нужда от достъп.

person Chris Becke    schedule 24.01.2010
comment
Мисля, че сте прав, може би данните на HBITMAP се съхраняват в режим на ядрото (или видеокарта), така че мога да видя само много малко използване на паметта в диспечера на задачите или изследователя на процеси (от sysinternals). Но не знам как да проверя тази точка. - person ddh; 25.01.2010
comment
Да, прав си. Ако използвам CreateDIBSection, данните се съхраняват в потребителското пространство, а не в ядрото. Благодаря ти :) - person ddh; 25.01.2010
comment
CreateDIBSection трябва, ако моето разбиране за съпоставянето на паметта и режима на ядрото е правилно, да използва както ядрото, така и потребителското пространство. - person Chris Becke; 25.01.2010