Фрагментация памяти WPF - PullRequest
1 голос
/ 15 мая 2009

У меня есть проблема фрагментации памяти.

Мы недавно портировали наше приложение WinForms в приложение WPF. Это приложение выполняет некоторую обработку изображений, и эта обработка всегда работала в версии приложения WinForms. Заходим в WPF, и обработка умирает. Отладка в библиотеке приводит к гибели в случайных местах, но всегда с массивом, который обнуляется, т. Е. Распределение не удалось.

Сама обработка выполняется в библиотеке C ++, вызываемой p / invoke, и требует довольно много памяти; если данное изображение имеет размер N x M пикселей, то изображение имеет размер N x M x 2 байта (каждый пиксель является коротким без знака, и это изображение в оттенках серого). Во время обработки создаются пирамиды изображений, которые находятся в плавающем пространстве, поэтому общее использование памяти будет составлять N x M x (2 + 2 + 4 + 4 + 4 + 4), где первое 2 - это вход, второе 2 - это выход, первые 4 - это входные данные в числах с плавающей запятой, вторые 4 - это изображения разности 0-го уровня, а последние две четверки - это остальная часть пирамиды (так как они являются пирамидами, и каждый уровень составляет половину размера в каждом направление, эти 4s являются верхними границами). Таким образом, для изображения размером 5000x6000 это 600 МБ, что должно прекрасно вписаться в память.

(Существует вероятность того, что использование маршаллинга увеличивает требование к памяти еще на N x M x 4, т. Е. Входные и выходные изображения на стороне C #, а затем те же массивы копируются на сторону C ++, - может быть требование маршаллинга быть больше?)

Насколько фрагментирован WPF по сравнению с WinForms? Есть ли способ консолидировать память перед запуском этой обработки? Я подозреваю, что фрагментация является проблемой из-за случайного характера поломок, когда они происходят, и что это всегда проблема выделения памяти.

Или мне следует полностью избежать этой проблемы, сделав обработку отдельным процессом, с передачей данных через сокеты или чем-то подобным?

Ответы [ 4 ]

3 голосов
/ 15 мая 2009

Если я правильно прочитал, ошибка выделения памяти происходит на неуправляемой стороне, а не на управляемой. Кажется странным тогда винить WPF. Я признаю, что вы делаете свой вывод, основываясь на том факте, что «он работал в WinForms», но, скорее всего, изменений больше, чем просто. Вы можете использовать такой инструмент, как .NET Memory Profiler , чтобы увидеть различия между тем, как приложение WPF и приложение WinForms обрабатывают память. Вы можете обнаружить, что ваше приложение делает то, чего вы не ожидаете. :)

За комментарий: Да, я понимаю. Если вы уверены, что вы исключили такие вещи, как изменения среды, я думаю, вам нужно взять копию BoundsChecker и Memory Profiler (или DevPartner Studio ) и покопаться в посмотрите, что мешает распределению памяти.

1 голос
/ 15 мая 2009

Я предполагаю, что GC перемещает вашу память. Попробуйте закрепить память в неуправляемой стране, если у вас есть необработанный указатель на массив, и открепить ее как можно скорее. Вполне возможно, что WPF заставляет GC запускаться чаще, что объясняет, почему это происходит чаще, а если это GC, то это объясняет, почему это происходит в случайных местах в вашем коде.

Редактировать: Из любопытства, не могли бы вы также заранее выделить всю вашу память заранее (я не вижу кода, поэтому не знаю, возможно ли это), и убедитесь, что все ваши указатели не -Ну, так что вы можете убедиться, что это на самом деле происходит в распределении памяти, а не какая-то другая проблема?

0 голосов
/ 14 января 2010
0 голосов
/ 15 мая 2009

Звучит так, будто вы хотите быть более внимательным к управлению памятью в целом; то есть: либо запустить механизм обработки в отдельном адресном пространстве, которое тщательно управляет памятью, либо предварительно выделить достаточно большой кусок, прежде чем память станет слишком фрагментированным, и управлять изображениями только в этой области. Если вы совместно используете адресное пространство со средой выполнения .NET в длительном процессе и вам нужны большие смежные области, в какой-то момент он всегда может потерпеть неудачу. Просто мой 2с.

...