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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Удаление объектов 
:(
    Опции темы
Freeman
Дата 23.2.2005, 19:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Начал изучать C# и решил написать простенький список, но столкнулся с проблемой удаления объектов. Я знаю что в С# автоматическое удаление, но что если надо удалить элемент сразу, не дожидаясь пока это сделает сборщик мусора.
Если можно ответ, пояснить примером.
PM MAIL   Вверх
Domestic Cat
Дата 23.2.2005, 20:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

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



Объект подлежит удалению тогда, когда на него нет ссылок - например, ссылка на него была в локальной переменной, или ты ее занулил. Тогда можно вызвать сборщик мусора, который и уберет ненужный объекt:

Код

myObject = null;
GC.Collect();


С другой стороны, в постоянном вызове сборщикa ничего хорошего нет .


--------------------

PM   Вверх
Gazon
Дата 23.2.2005, 23:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата
С другой стороны, в постоянном вызове сборщикa ничего хорошего нет .

И с ним многие советуют не связываться ни в коем случае.
--------------------
Чем больше узнаешь, тем больше не знаешь, но до истины всегда можно добраться.
PM MAIL   Вверх
Tomcat
Дата 24.2.2005, 11:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Был у меня однажды случай. Прога была, в принципе, простенькая. Суть заключалась в том, что она собирала кучу информации с файлов, а потом одним махом заносила ее в БД на SQL Server. По началу все было не плохо... Но затем пошли файлы, у которых эта куча была слишком большой, да такой, что вылетал Out of memory. Когда посмотрели загруженность памяти, поняли, что все вполне понятно, выделяемая под процесс проги область разрасталась до 2-3 Гб, да плюс еще и SQL Server ел не мало.
Ну что же, и все из-за не удаленных промежуточных объектов, появляющихся при обработке файлов. Так вот, код типа:
Код

myObject = null;
GC.Collect();

не помогал вовсе. Беглый просмотр документации привел к выводу, что необходимо GC.Collect() вызывать два раза. Это тоже не помогало.
Нам тогда повезло, появились другие исходные данные, которые были намного удобней для обработки, на том и выехали.
PM MAIL   Вверх
Дрон
Дата 24.2.2005, 15:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java-ненавистник :)
****


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

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



Посмотри метод Dispose для объёктов. Может поможет smile


--------------------
Да. Именно так.
PM   Вверх
Freeman
Дата 24.2.2005, 22:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



К сожалению ни один вариант не решил проблемы, но может я что-то не так делаю, вот код
Код

class List
{
 private class Node : IDisposable
 {
  public int val;
  public Node next;

  public Node() { }
  public Node(int v)
  {
   val = v;
  }
  public Node(int v, Node n)
  {
   val = v;
   next = n;
  }

  public void Dispose()
  {
   
  }
 }

 private int count;
 private Node head;

 public void Insert(int v)
 {
  Node pn = head, last = null, pnew;
 
  for (; pn != null  &&  pn.val <= v; last = pn, pn = pn.next);

  pnew = new Node(v);
  if (last == null)
  {
   pnew.next = head;
   head = pnew;
  }
  else
  {
   pnew.next = pn;
   last.next = pnew;
  }

  count++;
 }

 public void Show()
 {
  Node pn = head;
  int i = 0;

  Console.WriteLine("List...");
  while (pn != null)
  {
   Console.WriteLine("[{0}]: {1}", i, pn.val);
   i++;
   pn = pn.next;
  }
 }

 public bool Delete(int v)
 {
  Node pn = head, last = null;

  for (; pn != null && pn.val != v; last = pn, pn = pn.next);

  if (pn != null)
  {
   if (last != null)
   {
    last.next = pn.next;
   }
   else
   {
    head = pn.next;
   }
  }
  else
  {
   return false;
  }

  //так не помогает pn = null;
  //и так не помогаетGC.Collect();
  pn.Dispose(); //и так тоже
  count--;
  return true;
 }
}


а это тест

Код

class Program
{
 static void Main(string[] args)
 {
  List d = new List();
  int NN = 1000000;

  for (int i = NN-1; i > -1; i--)
  {
   d.Insert(i);
  }

  for (int i = 0; i < NN; i++)
  {
   d.Delete(i);
  }
 }
}


PM MAIL   Вверх
Domestic Cat
Дата 24.2.2005, 23:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

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



Код

private class Node : IDisposable
  {
   public int val;
       public Node next;
//....
         public void Dispose()
       {
             next = null; // на всякий случай 
     }
  }



Код

public bool Delete(int v)
  {
//...
    pn.Dispose(); 
    pn = null;
       count--;
         return true;
  }


1. Как ты определил что "не помогает"?
2. На кой из-за одного объекта в пару десяков байт вызывать сборщик?
Вроде никаких ошбок не вижу, хотя названия переменным можно было бы и поприличее дать.


--------------------

PM   Вверх
Plamenk
Дата 25.2.2005, 12:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



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

Что касается однозначного удаления объекта, то необходимо ИХМО как-то использовать GC и удалять все ссылки на объект!
PM MAIL   Вверх
Freeman
Дата 25.2.2005, 19:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



to Domestic Cat
Цитата
Как ты определил что "не помогает"?

Очень просто запустил тест и посмотрел в диспетчере задач, там есть объем занятой памяти, при удалении память должна освобождаться а она не освобождается

Цитата
На кой из-за одного объекта в пару десяков байт вызывать сборщик?

Так на всякий случай smile)

to Plamenk
Цитата
удалять все ссылки на объект!

Так они и так все удаляются, все локальные ссылки уничтожаются при выходе из функции,
есть правда указатели next ,но и они при таком коде

Код

public void Dispose()
{
     next = null;
}

они тоже обнуляются, так что не остаются никаких действующий ссылок на удаленный элемент.

Это сообщение отредактировал(а) Freeman - 25.2.2005, 19:57
PM MAIL   Вверх
Domestic Cat
Дата 25.2.2005, 20:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

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



Цитата
Очень просто запустил тест и посмотрел в диспетчере задач, там есть объем занятой памяти, при удалении память должна освобождаться а она не освобождается


Дык посмотрi нa свой код - у тебя удаление идет в цикле. Расходуешь памяти ты немного, потом все объекты удаляешь. Вполне возможно что сборщик запускается при удалении, но диспетчер не успевает отобразить изменениe памяти.

[Offtop]
Кстати, вопрос : есть ли что нибудь наподобиe флагa -verbose:gc , как в Java?
[/Offtop]


--------------------

PM   Вверх
Freeman
Дата 25.2.2005, 22:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



to Domestic Cat
Проблема не в диспетчере, потому что точно такой же код написанный на обычном C++, работает как надо и диспетчер отображает освобождение памяти в реальном времени.
PM MAIL   Вверх
Дрон
Дата 26.2.2005, 01:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java-ненавистник :)
****


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

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



Цитата(Domestic @ 25.2.2005, 20:07)
Вполне возможно что сборщик запускается при удалении, но диспетчер не успевает отобразить изменениe памяти.

Сборщик мусора запускается тогда, когда сочтёт нужным.


Цитата(Domestic @ 25.2.2005, 20:07)
Кстати, вопрос : есть ли что нибудь наподобиe флагa -verbose:gc , как в Java?

А что он делает?

Это сообщение отредактировал(а) Дрон - 26.2.2005, 01:52


--------------------
Да. Именно так.
PM   Вверх
Domestic Cat
Дата 26.2.2005, 03:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

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



Цитата
Сборщик мусора запускается тогда, когда сочтёт нужным.


Любой сборщик запускается когда захочет smile

Цитата
А что он делает?


Вывводит инфу - сколько с какой области хипа собрано. В Java есть поколения, только не 1, 2, 3 как в .НЕТ, а молодое и старое.
Что-то вроде
Цитата

.....
[GC 622K->110K(1984K), 0.0010317 secs]
[GC 622K->110K(1984K), 0.0010261 secs]
[GC 622K->110K(1984K), 0.0010359 secs]
[GC 622K->110K(1984K), 0.0010300 secs]
[GC 622K->110K(1984K), 0.0011647 secs]
[GC 622K->110K(1984K), 0.0010147 secs]
[GC 622K->110K(1984K), 0.0011021 secs]
[GC 622K->110K(1984K), 0.0010283 secs]
[GC 622K->110K(1984K), 0.0010306 secs]
[GC 622K->110K(1984K), 0.0010174 secs]
[GC 622K->110K(1984K), 0.0010345 secs]
[GC 622K->110K(1984K), 0.0018662 secs]
[GC 622K->110K(1984K), 0.0012367 secs]
.....



--------------------

PM   Вверх
Freeman
Дата 26.2.2005, 18:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Я вообще думал что это простой вопрос, неужели никто не делал каких-нибудь динамических структур на C#, хоть малюсенький дин. стек smile
PM MAIL   Вверх
Дрон
Дата 26.2.2005, 19:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java-ненавистник :)
****


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

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



Цитата(Freeman @ 26.2.2005, 18:36)
Я вообще думал что это простой вопрос, неужели никто не делал каких-нибудь динамических структур на C#, хоть малюсенький дин. стек smile

А в чём проблема? smile

Domestic Cat
Нет. По крайней мере, я такого не видел.


--------------------
Да. Именно так.
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

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


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

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


 




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


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

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