Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Заставить убрать обьекты с памяти. Коллекция и частичное удаление елементов 
V
    Опции темы
Bladerender
Дата 24.5.2010, 11:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 19.7.2007

Репутация: нет
Всего: нет



Исходные данные.

Код

//Из обьектов этого класса будет состоять колекция
class MyObj
{
   //куча всяких полей, методов, свойств и т.д.
}

//Колекция, с которой нужно будет разобраться. 
List<MyObj> collection = new List<MyObj>();

//Не суть важно. Показать, что коллекция заполняется
collection = FillCollection(param,param1,param1);


Коллекция занимает в памяти ~500 мегабайт.

Код

//Этот код действительно освобождает все 500 мегабайт
collection.Clear();
GC.Collect();


Код

//Этот код ничего не освобождает (почему, я ж так понимаю, что все 500 мегабайт остались без указателя на них и их можно освободить)
collection = null; или collection = new new List<MyObj>();
GC.Collect();



Код

//Этот код тоже естественно ничего не освобождает (исходя из того, что null выше был безполезен)
for(int i=0;i<collecion.Count;i++)
{
collection[i] = null;
}
GC.Collect();


Я так чувствую, что не хватает мне теоретических знаний. Хотя о GC я много читал и был уверен что потеря ссылки nullом приведет к освобождению памяти. 
Натолкните на правильную мысль. 

К чему собственно эти все разбирательства. Меня интересует именно последний блок кода, т.к. после обработки елемента колекции, мне он уже не нужен, и я хочу, что бы он сразу убирался из памяти.





PM MAIL   Вверх
Ram1reS
Дата 24.5.2010, 14:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 141
Регистрация: 25.4.2008
Где: Москва

Репутация: 3
Всего: 5



Каким образом Вы определяете что память не освобождена?
GC какбэ недерминировано мусор собирает по необходимости и подгонять его GC.Collect'ами - в большинстве случаев незачем.

ЗЫ. Объекты таких размеров, насколько я понимаю, уходят в LOH, который при сборке не дефрагментируется, так что можете напороться на OOM.

Это сообщение отредактировал(а) Ram1reS - 24.5.2010, 14:46
--------------------
 
PM MAIL ICQ   Вверх
Rohoss
Дата 24.5.2010, 19:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начальник интернета
***


Профиль
Группа: Завсегдатай
Сообщений: 1308
Регистрация: 9.10.2006
Где: Matrix

Репутация: 2
Всего: 18



Цитата(Ram1reS @  24.5.2010,  14:44 Найти цитируемый пост)
Каким образом Вы определяете что память не освобождена?

можно определить по использованной в системе памяти 


--------------------
Файловый менеджер Explorer.Net скачать  video
PM ICQ   Вверх
Pilger
Дата 24.5.2010, 20:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 257
Регистрация: 10.5.2008
Где: Германия

Репутация: нет
Всего: нет





--------------------
Ein Leben nach der Schleife existiert, nur wenn die Schleife terminiert.
PM MAIL ICQ   Вверх
Bladerender
Дата 25.5.2010, 00:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 19.7.2007

Репутация: нет
Всего: нет



Каким образом Вы определяете что память не освобождена?
Смотрю по ТаскМенеджеру. В первом случае освобождалось. Во всех остальных - нет. 
Pilger Ну я типа почти так и сделал... Написал свой метод класса MyObj, который делает освобождение полям обьекта (колекции чистит, стринги нулит и т.д.). И потом в цыкле, после отработки елемента, вызывал ему свой Dispose(). Получилось.
Объекты таких размеров, насколько я понимаю, уходят в LOH, который при сборке не дефрагментируется, так что можете напороться на OOM.
Я так понимаю, что если объект целиком диспосить, то он тогда туда уходит (что-то типа как я нулил всю колекцию). Вообще этот LOH очень интерестная тема. Давайте создадим отдельную тему и там обсосем это... Очень уж эта память в .Net постоянно куда-то девается...
PM MAIL   Вверх
PashaPash
Дата 25.5.2010, 12:14 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1233
Регистрация: 3.1.2008

Репутация: 13
Всего: 49



Если нужно сначала построить длинный список объектов, а потом для каждого объекта что-то сделать - используй yield/IEnumerable, не создавай огромных массивов.

Pilger, вот так не надо делать. IDisposable не для того предназначен.

Цитата(Bladerender @  25.5.2010,  00:13 Найти цитируемый пост)
Смотрю по ТаскМенеджеру. В первом случае освобождалось. Во всех остальных - нет. 

Не смотри по таскманагеру. Он врет.

Цитата(Bladerender @  25.5.2010,  00:13 Найти цитируемый пост)
Pilger Ну я типа почти так и сделал... Написал свой метод класса MyObj, который делает освобождение полям обьекта (колекции чистит, стринги нулит и т.д.). И потом в цыкле, после отработки елемента, вызывал ему свой Dispose(). Получилось.

Это бесполезное занятие. Достаточно перестать ссылаться на collection, чтобы память под коллекцию, и под все ее объекты могла быть собрана. Перестать ссылаться - не обязательно присвоить null. Даже наоборот - присвоение null продлевает время жизни переменной. 

Механизм работы GC на пальцах: 
GC выделяет под managed-объекты здоровый кусок памяти, который называется managed heap. Память под managed heap выедается относительно большими кусками. Эти куски (а заодно и память, выделенную под код) ты видишь в task manager. А может и не эти - там минимум 3 разных колонки с "памятью" показыватюся, и невозможно угадать на какую именно ты смотришь smile

Внутри managed heap GC выделяет память под объекты. При выделении очередного объекта GC решает что надо бы собрать мусор. Он находит все объекты, на которые есть ссылки в коде, и перекладывает их поплотнее в памяти. Те объекты, на которые ссылок не было при этом затираются.

По каким признакам GC решает запустить сборку мусора - заранее не известно, критерий меняется от версии к версии.

LOH - это отдельный кусок кучи, в котором создаются объекты больше 85000 байт. Отличие LOH от основной кучи - в нем объекты при сборке мусора не перекладываются. Эдакий хак чтобы не перекладывать большие объемы данных. Объект изначально создается или в общей куче, или в LOH, и не "уходит туда-сюда при диспоузе". По той причине что размер объекта в .net - постоянная величина.

Причина по которой не стоит вручную выставлять переменные в null:
Локальная переменная считается корнем в течении своей жизни. Т.е. если она на что-то ссылается - то сборщик мусора считает этот "что-то" достижимым объектом.
Конец жизни переменной:
 - до конца области видимости в Debug
 - до последнего упоминания ее в коде в Release

вписывая collection = null ты "отпускаешь" объект в мусор в Debug. И наоборот, принудительно удерживаешь объект до этой строчки в Release.

Причина по которой не стоит делать такой "Dispose" - как только ты перестанешь ссылаться на объект, он, и все его зависимые куски могут быть собраны GC. Делая ручной Dispose и зануляя ссылки ты получаешь видимое "освобождение", т.к. за время работы "диспоуза" скорее всего происходит сборка мусора. При этом сам объект переживает эту сборку, переползая во первое/второе поколение, которое собирается очень редко. Т.е. ты ухудшаешь ситуацию в долгосрочной перспективе smile


--------------------
PM MAIL WWW   Вверх
jonie
Дата 25.5.2010, 12:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 22
Всего: 118



в системном мониторе есть счетчики производительности .NET - по ним надо судить, а не по таск менеджеру...


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
Bladerender
Дата 25.5.2010, 23:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 19.7.2007

Репутация: нет
Всего: нет



Т.е. ты ухудшаешь ситуацию в долгосрочной перспективе
На пальцах механизм я понимаю и потому и ждал, что оно все соберется и без моего вмешательства. А на практике получилось, что без моего Dispose этот массив болтался в памяти и в итоге через 3 часа работы программы получал outOfMemory.
PM MAIL   Вверх
PashaPash
Дата 26.5.2010, 00:07 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1233
Регистрация: 3.1.2008

Репутация: 13
Всего: 49



Bladerender, out of memory ты получил из-за фрагментации LOH. Т.е. болтались не сами объекты - они скорее всего были собраны. В LOH выделяется только сам массив ссылок. Т.е. если даже все элементы задиспоужены - LOH уже фрагментирован.

Вообще стоит взять профайлер памяти и посмотреть на приложение. Может там действительно где-то ссылка на массив из статической переменной smile


--------------------
PM MAIL WWW   Вверх
uranpro
Дата 28.5.2010, 13:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 571
Регистрация: 7.5.2008
Где: Moscow city

Репутация: 1
Всего: 1



ну и от event`ов не забудь отписаться)


--------------------
I want a perfect soul
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0876 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.