![]() |
Модераторы: Partizan, gambit |
![]() ![]() ![]() |
|
Freeman |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 44 Регистрация: 29.11.2003 Репутация: нет Всего: нет |
Начал изучать C# и решил написать простенький список, но столкнулся с проблемой удаления объектов. Я знаю что в С# автоматическое удаление, но что если надо удалить элемент сразу, не дожидаясь пока это сделает сборщик мусора.
Если можно ответ, пояснить примером. |
|||
|
||||
Domestic Cat |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5452 Регистрация: 3.5.2004 Где: Dallas, US Репутация: 9 Всего: 172 |
Объект подлежит удалению тогда, когда на него нет ссылок - например, ссылка на него была в локальной переменной, или ты ее занулил. Тогда можно вызвать сборщик мусора, который и уберет ненужный объекt:
С другой стороны, в постоянном вызове сборщикa ничего хорошего нет . -------------------- |
|||
|
||||
Gazon |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 128 Регистрация: 9.1.2005 Репутация: 3 Всего: 8 |
И с ним многие советуют не связываться ни в коем случае. --------------------
Чем больше узнаешь, тем больше не знаешь, но до истины всегда можно добраться. |
|||
|
||||
Tomcat |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 86 Регистрация: 4.4.2003 Где: Гродно, Беларусь Репутация: 2 Всего: 2 |
Был у меня однажды случай. Прога была, в принципе, простенькая. Суть заключалась в том, что она собирала кучу информации с файлов, а потом одним махом заносила ее в БД на SQL Server. По началу все было не плохо... Но затем пошли файлы, у которых эта куча была слишком большой, да такой, что вылетал Out of memory. Когда посмотрели загруженность памяти, поняли, что все вполне понятно, выделяемая под процесс проги область разрасталась до 2-3 Гб, да плюс еще и SQL Server ел не мало.
Ну что же, и все из-за не удаленных промежуточных объектов, появляющихся при обработке файлов. Так вот, код типа:
не помогал вовсе. Беглый просмотр документации привел к выводу, что необходимо GC.Collect() вызывать два раза. Это тоже не помогало. Нам тогда повезло, появились другие исходные данные, которые были намного удобней для обработки, на том и выехали. |
|||
|
||||
Дрон |
|
|||
![]() Java-ненавистник :) ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3179 Регистрация: 29.12.2002 Где: Санкт-Петербург Репутация: 24 Всего: 92 |
Посмотри метод Dispose для объёктов. Может поможет
![]() -------------------- Да. Именно так. |
|||
|
||||
Freeman |
|
||||
![]() Новичок Профиль Группа: Участник Сообщений: 44 Регистрация: 29.11.2003 Репутация: нет Всего: нет |
К сожалению ни один вариант не решил проблемы, но может я что-то не так делаю, вот код
а это тест
|
||||
|
|||||
Domestic Cat |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5452 Регистрация: 3.5.2004 Где: Dallas, US Репутация: 9 Всего: 172 |
1. Как ты определил что "не помогает"? 2. На кой из-за одного объекта в пару десяков байт вызывать сборщик? Вроде никаких ошбок не вижу, хотя названия переменным можно было бы и поприличее дать. -------------------- |
||||
|
|||||
Plamenk |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 258 Регистрация: 18.2.2003 Репутация: 1 Всего: 3 |
Вообще использование интерфейса IDisposable, никак не связано с удалением объекта!
Если класс реализует данный интерфейс, то подразумевается что он использует неуправляемые ресурсы и в функции Dispose просто происходит их очистка, так как сборщик мусора сам не сбособен освобождать такие ресурсы! Что касается однозначного удаления объекта, то необходимо ИХМО как-то использовать GC и удалять все ссылки на объект! |
|||
|
||||
Freeman |
|
||||||||
![]() Новичок Профиль Группа: Участник Сообщений: 44 Регистрация: 29.11.2003 Репутация: нет Всего: нет |
to Domestic Cat
Очень просто запустил тест и посмотрел в диспетчере задач, там есть объем занятой памяти, при удалении память должна освобождаться а она не освобождается
Так на всякий случай ![]() to Plamenk
Так они и так все удаляются, все локальные ссылки уничтожаются при выходе из функции, есть правда указатели next ,но и они при таком коде
они тоже обнуляются, так что не остаются никаких действующий ссылок на удаленный элемент. Это сообщение отредактировал(а) Freeman - 25.2.2005, 19:57 |
||||||||
|
|||||||||
Domestic Cat |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5452 Регистрация: 3.5.2004 Где: Dallas, US Репутация: 9 Всего: 172 |
Дык посмотрi нa свой код - у тебя удаление идет в цикле. Расходуешь памяти ты немного, потом все объекты удаляешь. Вполне возможно что сборщик запускается при удалении, но диспетчер не успевает отобразить изменениe памяти. [Offtop] Кстати, вопрос : есть ли что нибудь наподобиe флагa -verbose:gc , как в Java? [/Offtop] -------------------- |
|||
|
||||
Freeman |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 44 Регистрация: 29.11.2003 Репутация: нет Всего: нет |
to Domestic Cat
Проблема не в диспетчере, потому что точно такой же код написанный на обычном C++, работает как надо и диспетчер отображает освобождение памяти в реальном времени. |
|||
|
||||
Дрон |
|
||||
![]() Java-ненавистник :) ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3179 Регистрация: 29.12.2002 Где: Санкт-Петербург Репутация: 24 Всего: 92 |
Сборщик мусора запускается тогда, когда сочтёт нужным.
А что он делает? Это сообщение отредактировал(а) Дрон - 26.2.2005, 01:52 -------------------- Да. Именно так. |
||||
|
|||||
Domestic Cat |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5452 Регистрация: 3.5.2004 Где: Dallas, US Репутация: 9 Всего: 172 |
Любой сборщик запускается когда захочет ![]()
Вывводит инфу - сколько с какой области хипа собрано. В Java есть поколения, только не 1, 2, 3 как в .НЕТ, а молодое и старое. Что-то вроде
-------------------- |
||||||
|
|||||||
Freeman |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 44 Регистрация: 29.11.2003 Репутация: нет Всего: нет |
Я вообще думал что это простой вопрос, неужели никто не делал каких-нибудь динамических структур на C#, хоть малюсенький дин. стек
![]() |
|||
|
||||
Дрон |
|
|||
![]() Java-ненавистник :) ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3179 Регистрация: 29.12.2002 Где: Санкт-Петербург Репутация: 24 Всего: 92 |
А в чём проблема? ![]() Domestic Cat Нет. По крайней мере, я такого не видел. -------------------- Да. Именно так. |
|||
|
||||
Domestic Cat |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5452 Регистрация: 3.5.2004 Где: Dallas, US Репутация: 9 Всего: 172 |
Нашел я как делать.
1. Запускаем perfmon.exe из Выполнить. 2. Кликаем правой кнопкой на правой панели и выбираем "Добавить счетчики..." 3. Выбираем объект Память CLR .NET и Выбрать все счетчики 4. Нажимаем Добавить и Закрыть 5. Запускаем ченить НЕТовское и смотрим, лучше под видом "Просмотр отчета". -------------------- |
|||
|
||||
Freeman |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 44 Регистрация: 29.11.2003 Репутация: нет Всего: нет |
to Дрон
Проблема в том, что удаление не работает так как должно. |
|||
|
||||
Domestic Cat |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5452 Регистрация: 3.5.2004 Где: Dallas, US Репутация: 9 Всего: 172 |
Все на самом деле работает. Если не веришь - вот пример:
Результат:
64200 - 52200 = 12000 байт Всего объектов 1000 - значит, по 12 байт на каждый Объект, как и должно быть. То есть, все объекты после метода RemoveAllFromList были вычищены. -------------------- |
||||||
|
|||||||
Freeman |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 44 Регистрация: 29.11.2003 Репутация: нет Всего: нет |
to Domestic Cat
Я не спорю с ArrayList все работает, но я не думаю что в реальном приложении Вы будете пользоваться таким списком. По-крайней мере из-за двух причин : 1. Слишком медленный(в части удаления), запустите Ваш пример не на 1000, а на 100000 и больше. 2. Расход памяти одинаковый для любых объектов, и равен <размер списка>*sizeof(Object), что наводит на мысль что в ArrayList хранятся не сами объекты, а лишь ссылки на них, причем ссылки типа Object, из-за этого возникает дополнительная трудоемкость, более того если со ссылочными типами происходит только преобразование типа, то со структурными типами происходит упаковка объекта, что также не улучшает эффективность данной структуры. 3. Если можно, не могли бы Вы объяснить следующую вешь. Was: 211380 Before: 1938880 After: 738868 почему разница между After - Was, такая большая? А вот если Вы поставите в нужные места в моем незамысловатом коде следующий код
то получатся следующие результаты Was: 216656 Before: 1819012 After: 219012 Тестирование в обоих случаях проводилось на 100000. |
|||
|
||||
Domestic Cat |
|
||||||||||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5452 Регистрация: 3.5.2004 Где: Dallas, US Репутация: 9 Всего: 172 |
Почему не буду, буду. Свое-то точно сочинять не собираюсь.
ArrayList по идее должен быть реализован в виде массива. Удаление действительно долго идет, но зато доступ быстрее.
Само собой
Да, Объект, иначе он бы вообще ничего не смог хранить. Не устраивает - есть generics.
А что ж делать? Ну не пользуйся структурами в таком случае, они не для этого предназначены.
Помимо твоих объектов, нахипе создаются и другие, которые ты "не видишь". Например простейшая операция
создает как минимум 3 объекта. Помимо этого, getTotalMemory не всегда выдает точное значение.
Вроде ж все пучком, объекты удаляются, разве не так? -------------------- |
||||||||||||||||
|
|||||||||||||||||
Freeman |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 44 Регистрация: 29.11.2003 Репутация: нет Всего: нет |
Объекты удаляются лишь виртуально, физическая память не освобождается. Это аналогично работе "Корзины" в Винде, вроде бы файлы удаляются, но место на диске все равно жрут, по не очистишь
![]()
И как я понял они не удаляются. Список это достаточно простая структура, и она заранее реализована. Но если мне нужно допустим какое-нибудь дерево или граф, я что-то не нашел ничего подобного. |
|||
|
||||
Дрон |
|
|||
![]() Java-ненавистник :) ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3179 Регистрация: 29.12.2002 Где: Санкт-Петербург Репутация: 24 Всего: 92 |
Freeman
Чегой-то я не понимаю, в чём же всё-таки у тебя проблема? Такова уж особенность систем с автоматической сборкой мусора ![]() Хочется самостоятельно управлять памятью? Так напиши на Си какую-нибудь библиотеку, сделай там функции аналогичные malloc и free, подключи в .NET и используй их (хотя это бредовая и бесполезная идея) ![]() -------------------- Да. Именно так. |
|||
|
||||
Freeman |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 44 Регистрация: 29.11.2003 Репутация: нет Всего: нет |
Проблема была в том что удаление работало на половину, из кучи объекты удалялись, а из физической памяти нет. Но в конце концов я понял в чем была причина. Все дело было в сборщике мусора, он не работает в Visual Studio 2005 Beta 1, по крайней мере так как должен. Но у меня имеется также и 2003 там все работает прекрасно.
|
|||
|
||||
![]() ![]() ![]() |
Прежде чем создать тему, посмотрите сюда: | |
|
Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов. Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :) Так же не забывайте отмечать свой вопрос решенным, если он таковым является :) Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |