GDI + в 64-битных системах - PullRequest
       15

GDI + в 64-битных системах

0 голосов
/ 16 апреля 2010

Наша система использует много больших растровых изображений (System.Drawing.Bitmap), и иногда нам не хватает памяти и появляется ошибка «Параметр не действителен». Это имеет смысл, поскольку может быть трудно выделить большой непрерывный кусок памяти.

Итак, вопрос в том ... Если бы мы обновили систему до 64-битной, исчезла бы эта проблема?

Ответы [ 6 ]

3 голосов
/ 16 апреля 2010

Если , то это проблема выделения памяти (из-за фрагментации кучи больших объектов вполне возможно, что у вас возникнут проблемы с выделением фрагментов по 100 МБ после загрузки примерно 20 изображений, даже если некоторые из них впоследствии они были выгружены), тогда переход на 64-битный должен помочь - гораздо большее адресное пространство должно дать кучу места для работы и, таким образом, облегчить симптомы.

Проблема с памятью должна вызывать исключение OutOfMemoryException, но возможно, что код обработки растровых изображений в .net это улавливает и эффективно преобразует в исключение InvalidParameterException. Однако существует вероятность, что существует другая проблема, связанная с размером / форматом изображений, и это действительно неверный параметр.

1 голос
/ 18 апреля 2010

В зависимости от того, как создается растровое изображение, будь то DDB, видеопамять DIB или системная память (используется видеопамять DDB, системная память DIB). Вам нужно будет использовать DotNet отражатель , чтобы определить, когда каждый из них создается в зависимости от используемого вами конструктора ... Например, DDB создается при переходе:

var bmp = new Bitmap(width, height, pixelDepth)

и это может иметь ограничение размера 5000x5000 на машине с небольшой видеокартой (то есть на серверах, на которых вы можете использовать веб-сервис), тогда как вы можете обнаружить, что вы можете загрузить растровое изображение 10000x10000 с помощью

var bmp = new Bitmap(pathToLargeFilename);

Мне не сильно повезло, когда я понял, как форсировать создание DIB в Dotnet (я думаю, что самым простым способом было бы ручное создание структуры Bitmap, ручное распределение памяти, а затем каким-то образом преобразовать его в растровое изображение. Или, возможно, лучше всего перейти на альтернативную библиотеку изображений, которая не использует видеопамять (есть довольно много открытых программ FreeImage , ImageMagick , Каир (хотя вам, по крайней мере, нужно будет получить GTK-пакеты от Mono для его запуска)

1 голос
/ 16 апреля 2010

В общем, когда вы начинаете играть с огромным растровым изображением в памяти, вы всегда сталкиваетесь с такой проблемой. Лучший способ избежать этого - разделить изображение на массив или нечто подобное, чтобы вы могли создать сетку.

С этого момента вам нужно только / нужно загрузить на экран то, что можно просмотреть, что сэкономит много памяти.

Это случилось со мной, когда я решил создать несколько игр, чтобы убить несколько раз.

Я решил создать игру Maze / Pipe, и пользователь мог выбирать количество столбцов и рядов. Я решил ограничить изображение до 10000 пикселей на 10000 пикселей.

Моя первая попытка, у меня была именно ваша проблема. ошибка за ошибкой за ошибкой, в основном проблема с памятью.

Я решил провести исследование о том, как делать то, что хотел, и нашел решение.

Я создал динамический 2-мерный массив (я решил ограничить его максимум 1000 на 1000) и просто поместил в него небольшое изображение размером 10х10 пикселей или что-то другое, что решит пользователь.

Когда это было сделано, проблема с памятью / скоростью загрузки / и т.д. ... просто исчезла.

использование памяти до того, как мое исправление было легко закончено, теперь использование памяти приложений составляет от 150 до 225 мегабайт оперативной памяти при использовании ограничения

Если вы хотите попробовать, скачайте это и зайдите в меню (Лабиринт) и поиграйте с настройкой: мои маленькие игры

0 голосов
/ 16 апреля 2010

Перед размещением этих больших растровых изображений вы можете попробовать вызвать GC.Collect (). У меня была именно эта проблема недавно, и это помогло. (Моей первой реакцией было также перейти на 64-разрядную версию, но добавить одну строку кода было немного проще.; -)

0 голосов
/ 16 апреля 2010

Существует ограничение на размер растрового изображения, которое вы можете создать в системе.

Проверьте http://www.efg2.com/Lab/Graphics/VeryLargeBitmap.htm для программы, которая может показать вам системный лимит.

Возможно, вы достигли этого предела.

0 голосов
/ 16 апреля 2010

Некоторое время назад я часто сталкивался именно с такого рода ошибками при разработке с Visual Studio 2008 в 64-разрядной системе Vista. Поэтому я думаю, что переход на 64-битную систему может увеличить шансы на успех и привести к тому, что ошибка будет возникать реже, но я не думаю, что переход на 64-битную систему полностью излечит ее.

Что мне помогло, так это ссылка: http://confluence.jetbrains.net/display/ReSharper/OutOfMemoryException+Fix

Это оболочка, которая заменяет политику выделения памяти, s.t. Вы склонны получать большие куски непрерывной памяти. Возможно, вы также можете использовать аналогичную политику выделения памяти в своем приложении, потому что эта должна была охватывать только Visual Studio.

...