tishi208 Ответов: 3

Как освободить память?


Я работаю над приложением, которое использует службы WCF. Эта служба получит вызов от какого-то другого приложения и вернет результат вызывающему абоненту. Ответ здесь находится в форме конкретного объекта, который относится к типу класса.

Когда это приложение дало ответ обратно вызывающему абоненту, даже тогда оно удерживает некоторую память. Поэтому я попробовал разные способы освободить эту память после завершения операции, но она все еще удерживает память. Способы, которыми я пытался решить эту проблему:

Что я уже пробовал:

Я создал один поток, прежде чем вернуть ответ, и вызвал функцию сна в течение 1 минуты. На этот раз сработало. Память уменьшается, и я получаю желаемый результат. это правильный путь?
Я также попытался утилизировать объект ответа в блоке finally, но в этом случае память уменьшается,но я не получил вывод.

Tomas Takac

Почему? Какова ваша мотивация для вмешательства в управление памятью? Вы ведь знаете, что память управляется автоматически в C# / .NET, не так ли?

tishi208

@Tomas Takac
Я знаю, что память управляется автоматически, но я хочу уменьшить размер потребления памяти после завершения операции, чего не происходит, поэтому я попытался дать явный вызов сборке мусора, чтобы решить эту проблему. Я знаю, что это не очень хорошая практика. Если у вас есть какие-либо другие решения, пожалуйста, дайте мне знать

Tomas Takac

Память не нужно освобождать сразу. Растет ли использование памяти с течением времени? Вы подозреваете утечку памяти? Затем вы должны использовать профилировщик памяти, чтобы найти источник проблемы.

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

И последнее, но не менее важное: обновите свой вопрос (через Улучшить вопрос) и добавьте немного кода, чтобы проиллюстрировать вашу проблему.

3 Ответов

Рейтинг:
0

Dave Kreskowiak

Если вы смотрите на Диспетчер задач, чтобы определить объем памяти, используемой вашим приложением, не делайте этого! Он лжет тебе.

В Диспетчере задач вы видите, сколько памяти зарезервировано для выполнения вашего приложения, а не сколько оно на самом деле использует.

Среда CLR .NET управляет выполнением вашего приложения и так называемой"управляемой кучей". Когда ваше приложение запускается, среда CLR запрашивает кусок памяти и помещает его в управляемую кучу. Экземпляры объектов, созданные вашим приложением, распределяются в управляемой куче очень быстро. Если в куче недостаточно памяти, среда CLR запросит еще один блок из Windows и снова добавит его в кучу. Это занимает дополнительное время, поэтому CLR пытается "заглянуть вперед", глядя на то, что выделяет ваше приложение, и расширяет кучу по мере необходимости, чтобы поддерживать высокую производительность вашего приложения.

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

Теперь, когда объекты больше не нужны вашему приложению, память освобождается, но не возвращается в Windows. Он возвращается в управляемую кучу.

Диспетчер задач ничего не знает о .NET CLR и зарезервированной им памяти. Все, что он видит, - это то, что говорит ему Windows. Windows говорит диспетчеру задач: "да, я дал этому процессу x объем памяти. Я понятия не имею, что он с ней делает."

Но есть также переговоры между Windows и .NET CLR. Если Windows начинает хватать памяти, он может попросить .Чистая среда CLR, чтобы вернуть память, он может избавить и .Чистая среда CLR будет с радостью бесплатно неиспользуемую память в управляемой куче и вернуть его в систему Windows.

Все это происходит автоматически, без вашего вмешательства. Диспетчер задач может сказать вам: "Эй, у нас кончается память!", а вы-нет. Windows просто не чувствовала необходимости идти и просить кого-либо вернуть ее .Чистые управляемые процессы.


Graeme_Grant

5 бы ... хорошо :)

Рейтинг:
0

Kornfeld Eliyahu Peter

Нет никакой приемлемой причины для принудительного освобождения памяти, хранящейся в GC...
(Единственное возможное приложение, когда вы можете лучше знать состояние памяти, чем GC, - это приложение с одним экземпляром/одним пользователем... Служба определенно не входит в их число...)
и... Это очень дорогая операция...
и... GC хранит память, потому что никто на нее не претендовал, потому что она никому сейчас не нужна-так зачем же ее освобождать?
Узнайте больше о GC: Вывоз Мусора | Майкрософт Документы[^]


Рейтинг:
0

Graeme_Grant

Статья Дэйва прекрасно объясняет управление памятью. Однако есть еще кое-что о том, как GC управляет памятью, что выходит за рамки этого форума. А быстро поиск Google[^] должно появиться много подробных статей, которые охватывают более тонкие моменты.

Единственное, о чем вам действительно нужно беспокоиться, - это об утечках памяти. Обычно это происходит только тогда, когда ресурсы не высвобождаются. Попытка заставить GC сделать это не исправит его, а только исправит код. Утечки памяти обычно можно увидеть в диагностических инструментах отладчика. Вот краткое вводное видео: Отладка утечек памяти с помощью новых средств диагностики памяти .NET / запуск Visual Studio 2013 | Channel 9[^]