Windows 7 x64 с приложением x86 .NET будет выбрасывать из памяти, если я не сделаю GC.Collect - PullRequest
1 голос
/ 07 апреля 2011

Я нашел решение, но поведение довольно тревожное, и подумал, что я спрашиваю здесь, видел ли кто-нибудь это тоже.

По сути, тот же двоичный файл, который был прикреплен к сборке в x86 (объяснит почемуниже) работает в x64 Windows 7 будет течь, если я не заставлю GC.Collect ()

Для объяснения:

  1. Приложение выполняет много растрового рендеринга (> 60 в / сек)
  2. Существует внешняя библиотека C ++ (управляемая C ++)
  3. Есть два потока (рабочий и пользовательский интерфейс)
  4. Есть обновление пользовательского интерфейса (статистика)
  5. Это происходит только на этом компьютере, Windows 7 x86 работает нормально.

Приложение вырастет до более 1,5 ГБ и в конечном итоге вызовет исключение «Недостаточно памяти».Чем быстрее (1) работает, тем быстрее исключение.

Для тех, кто готов сделать снимок (2), чтобы вызвать утечку, я протестировал ее удаление, и утечка осталась плюс , память освобождается нормально, если я выполняю GC.Collect (), которыйв моих книгах проблема .NET.

Спасибо.

Ответы [ 4 ]

0 голосов
/ 07 апреля 2011

ОК, за что стоит, вот мой улов.

Я видел точно такую ​​же проблему, с которой вы сталкиваетесь . Это было в .NET 2.0, но я работал с большими изображениями, и хотя я бы располагал изображениями , потребление памяти возрастало бы, пока я не вызову GC.Collect().

вручную.

Что еще было похоже? Хостинг! Моим приложением был неуправляемый EXE-файл, и он использовал COM для создания объекта класса .NET, доступного для COM. Это приведет к тому, что неуправляемый EXE будет содержать CLR.

В Windows X64 приложения X32 будут загружаться в режиме WOW (окна на окнах), который является аналогичным хостингом, который, как я считаю, может иметь аналогичные проблемы . Кажется, GC не может полностью понять потребление памяти, когда оно находится в размещенной среде.

0 голосов
/ 07 апреля 2011

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

Image.Dispose ()

Примечание. Всегда звоните утилизировать, прежде чем отпустите последнюю ссылку на Образ. В противном случае ресурсы это использование не будет освобождено до сборщик мусора называет изображение Метод Finalize объекта.

0 голосов
/ 07 апреля 2011

Вы должны .Dispose () ваших растровых изображений, когда вы перестанете их использовать. GC в конечном итоге будет собирать эту память (когда он запускает финализатор), даже если вы явно не вызываете .Dispose () - но GC не является волшебным лекарством от перераспределения памяти, если вы делаете это быстрее, тогда GC может собирать их, используя ресурсы, которые GC не может контролировать напрямую (неуправляемые ресурсы - именно это) - тогда механизм GC не сможет вам помочь.

Вызывая GC.Collect (0), вы заставляете GC обрабатывать дерево объектов и вызывать все финализаторы, если вы не вызываете его, тогда GC запускается, когда считает, что пришло время, и к тому времени уже слишком поздно. (из-за высокого уровня распределения).

0 голосов
/ 07 апреля 2011

Правильно ли вы утилизируете свои растровые изображения - и все другие одноразовые ресурсы, включая объекты GDI +?

using(Bitmap bitmap = ...)
{
    ... do your stuff
}

Вам нужно посмотреть на свое приложение, чтобы найти проблему - ясно, что 1,5 ГБ - это слишком много для 32-разрядного приложения. Тот факт, что на разных машинах с разными ОС происходит разное поведение, не означает, что вы должны винить ОС.

...