C# - Объекты сразу уничтожаются при выходе из объема?

Я имею, всегда шел со следующим:

  • Возрастание - Стрелка, подчеркивающая
  • Убывание - Стрелка, указывающая вниз

, По-моему, визуальное представление стрелки, указывающей/вниз наиболее точно, объясняет порядок сортировки.

11
задан sharkin 26 September 2009 в 09:45
поделиться

6 ответов

Нет, .Net и, следовательно, C # полагаются на управление памятью при сборке мусора. Таким образом, деструкторы (которые в .Net называются финализаторами) не вызываются до тех пор, пока GC не сочтет правильным уничтожать объекты.

Кроме того: большинство «обычных» объектов в C # не имеют деструкторов. Если вам нужен шаблон деструктора, вы должны реализовать интерфейс IDisposable с шаблоном удаления . На одноразовых объектах вы также должны убедиться, что метод Dispose вызывается либо с помощью с использованием ключевого слова , либо напрямую вызывая метод.

Для дальнейшего (надеюсь) пояснения: детерминированное удаление полезно в .Net, например когда вам нужно явно освободить ресурсы, которые не управляются средой выполнения .Net. Примеры таких ресурсов - дескрипторы файлов, соединения с базой данных и т. Д. Обычно важно, чтобы эти ресурсы были освобождены, как только они больше не нужны. Таким образом, мы не можем позволить себе ждать, пока сборщик мусора освободит их.

Чтобы получить детерминированное удаление (аналогичное поведению области видимости C ++) в недетерминированном мире сборщика мусора .Net, классы .Net полагаются на IDisposable интерфейс. Заимствуя из Dispose Pattern , вот несколько примеров:

Во-первых, создание экземпляра одноразового ресурса, а затем разрешение объекту выйти из области видимости, оставит его на усмотрение GC для удаления объекта:

1.    {
2.       var dr = new DisposableResource();
3.    }

] Чтобы исправить это, мы можем явно удалить объект:

1.    {
2.       var dr = new DisposableResource();
3.
4.       ...
5.
6.       dr.Dispose();
7.    }

Но что, если что-то пойдет не так между строками 2 и 6? Утилизировать не буду. Чтобы в дальнейшем гарантировать, что Dispose будет вызван независимо от каких-либо исключений, мы можем сделать следующее:

1.    var dr = new DisposableResource();
2.    try
3.    {
4.       ...
5.    }
6.    finally
7.    {
8.       dr.Dispose();
9.    }

Поскольку этот шаблон часто требуется, C # включает ключевое слово using для упрощения. Следующий пример эквивалентен приведенному выше:

1.    using (var dr = new DisposableResource())
2.    {
3.       ...
4.    }
27
ответ дан 3 December 2019 в 01:07
поделиться

В C # нет такой вещи, как деструктор, подобный C ++. (В C # существует другая концепция деструктора, также называемая финализатором, который использует тот же синтаксис, что и деструкторы C ++, но не имеет отношения к уничтожению объектов. Они предназначены для обеспечения механизма очистки неуправляемых ресурсов.) Сборщик мусора очистит объекты через некоторое время после того, как на них больше не будут ссылаться . Не сразу, и нет никакого способа гарантировать это.

К счастью, также нет реальной причины, по которой вы хотели бы гарантировать это. Если вам нужна память, тогда GC ее восстановит. Если нет, зачем беспокоиться о том, что вокруг все еще есть какой-то мусорный объект? Это не утечка памяти: сборщик мусора может ее найти и очистить в любое время.

4
ответ дан 3 December 2019 в 01:07
поделиться

Нет, это не гарантируется. Подобно таким языкам, как Java, в C # сборщик мусора запускается, когда это необходимо (то есть когда куча становится слишком полной). Однако, когда ваши объекты реализуют IDisposable , то есть у них есть метод Dispose () , и он должен быть вызван, тогда вы можете воспользоваться преимуществом , используя ключевое слово :

using (var foo = new DisposableObject()) {
    // do something with that
}

Таким образом, Dispose () будет вызываться сразу после выхода из этого с использованием блока .

Примечание: IDisposable встречается во многих типах, большинство особенно GDI +, но также соединения с базой данных, транзакции и т. д., так что это может быть действительно правильный шаблон здесь.

Примечание 2: За кулисами вышеупомянутый блок будет переведен в try / finally блок:

4
ответ дан 3 December 2019 в 01:07
поделиться

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

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

Это особенно заметно в программах на Java, если посмотреть на потребление памяти в диспетчере задач. Он растет и растет, и внезапно каждую минуту снова падает.

Не думаю, что в этом случае следует полагаться на сборщиков мусора. Даже если вы отследите, как они работают, вполне возможно, что в следующем выпуске они переопределят это.

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

Это особенно заметно в программах на Java, если посмотреть на потребление памяти в диспетчере задач. Он растет и растет, и внезапно каждую минуту снова падает.

Не думаю, что в этом случае следует полагаться на сборщиков мусора. Даже если вы отследите, как они работают, вполне возможно, что в следующем выпуске они переопределят его.

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

Это особенно заметно в программах на Java, если посмотреть на потребление памяти в диспетчере задач. Он растет и растет, и внезапно каждую минуту снова падает.

Это особенно заметно в программах на Java, если посмотреть на потребление памяти в диспетчере задач. Он растет и растет, и внезапно каждую минуту снова падает.

Это особенно заметно в программах на Java, если посмотреть на потребление памяти в диспетчере задач. Он растет и растет, и внезапно каждую минуту снова падает.

0
ответ дан 3 December 2019 в 01:07
поделиться

Нет. Объект на самом деле не выходит «за пределы области видимости», в отличие от ссылки на него (то есть переменной, которую вы используете для доступа к нему).

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

Если ваш объект является ресурсом (например, дескриптор файла, соединение с базой данных), он должен реализовать Интерфейс IDisposable (который обязывает объект реализовать метод Dispose () для очистки любых открытых соединений и т. Д.). В этом случае лучше всего будет создать объект как часть с использованием блока , так что когда этот блок будет завершен, ваше приложение автоматически вызовет метод objects Dispose () , который позаботится о закрытии вашего файла / соединения с базой данных / чего угодно.

например


using (var conn = new DbConnection())  
{ 
   // do stuff with conn  
} // conn.Dispose() is automatically called here.  

] с использованием блока - это всего лишь синтаксический сахар, который обертывает ваши взаимодействия с объектом conn в блоке try вместе с блоком finally , который только вызывает conn.Dispose ()

11
ответ дан 3 December 2019 в 01:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: