Вручную уничтожьте объекты C#

Я довольно плохо знаком с изучением C# (истории Java & C ++), и у меня есть вопрос о ручном мусоропроводе: даже возможно вручную уничтожить объект в C#? Я знаю о IDisposable интерфейс, но предполагают, что я имею дело с классом, который я не записал, и он не реализует его? Это не имело бы a .Dispose() метод, так, чтобы и using { } отсутствует, и .Finalize всегда также protected или private таким образом, это не опция также.

(Я просто пытаюсь изучить то, что возможно в C# в этом случае. Я предполагаю, перестало ли все остальное работать, я мог бы наследовать гипотетическое ImNotDisposable класс так, чтобы это действительно реализовало IDisposable.)

33
задан jadok 7 April 2014 в 13:13
поделиться

7 ответов

Вы не уничтожаете вручную объекты .NET. Это то, что такое управляемая среда, это все о.

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

Что вы можете сделать, это позвонить gc.collect () , чтобы заставить общий сбор. Однако это почти никогда не бывает хорошей идеи.

Вместо этого, вероятно, лучше просто притворяться Любой объект, который не использует неуправляемые ресурсы и не достижится ни одним другим объектом в вашей программе, сразу же разрушается. Я знаю, что это не происходит, но в этот момент объект - это просто блок памяти, как и любой другой; Вы не можете вернуть его, и он в конечном итоге будет собираться, так что он может быть просто мертвым для вас.

Одно окончательное примечание о idisposable . Вы должны использовать его только для типов, которые обернуты Unnained Ресурсы: такие вещи, как розетки, соединения базы данных, объекты GDI и т. Д., И случайное событие / делегата.

31
ответ дан 27 November 2019 в 18:14
поделиться

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

Furtnermore, так как окончательная обработка происходит на своем потоке, после запуска сборщика мусора следует вызвать WaitForPendingFinalizers.

GC.Collect(GC.MaxGeneration);
GC.WaitForPendingFinalizers();

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

Вообще говоря, класс, реализующий финализатор (деструктор) и не реализующий IDisposable, не одобряется. И все, что реализует IDisposable, должно называться логикой финализатора и подавляет себя от окончательной доработки при сборе мусора.

Джефф Рихтер недавно опубликовал небольшой трюк для , получив уведомление о том, что сборка мусора происходит .

Еще одна замечательная статья о Основах сборщика мусора и Подсказках производительности Рико Мариани (MSFT)

.
7
ответ дан 27 November 2019 в 18:14
поделиться

Вы не можете вручную уничтожить объект "типа C++ delete", все, что вы можете сделать, это просто закрыть все эксклюзивные ресурсы, которые объект приобрел и обнулить все ссылки на этот объект, так что ГК может его собрать, также не вызывайте GC.Collect() самостоятельно, процесс ГК дорогой, так как он должен приостановить все остальные потоки, чтобы безопасно собрать объекты из памяти, так что просто доверьтесь ГК, и он запустится, когда это понадобится.

2
ответ дан 27 November 2019 в 18:14
поделиться

Вот минимальный пример, основанный на документации :

class 3DPoint(object):
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z

     def __composite_values__(self):
        return (self.x, self.y, self.z)

class 3DLine(DeclarativeBase):
    start_point = sqlalchemy.orm.composite(
        3DPoint,
        Column('start_point_x', Integer, nullable=False),
        Column('start_point_y', Integer, nullable=False),
        Column('start_point_z', Integer, nullable=False),
    )
-121--4379059-

Если объект недоступен, можно вызвать GC.Collect () и объект будет уничтожен. Концепция IDisposable не имеет ничего общего с CLR и в основном предназначена для реализации кода пользователя для выполнения дополнительной логики удаления. Вызов Dispose () для объекта не освободит сам объект из памяти, хотя он вполне может утилизировать любые ресурсы, на которые ссылается этот объект.

Я должен добавить, что, хотя то, что я сказал, является способом достижения этого, в 99,9999% приложений вы никогда не должны вызывать GC.Collect () , потому что это часто ухудшает производительность вашего приложения, а не улучшает его.

-121--2532479-

Нет, невозможно уничтожить определенный объект.

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

6
ответ дан 27 November 2019 в 18:14
поделиться

Если объект не доступен, то вы можете вызвать Gc.collect () и объект будет уничтожен. Концепция IDSPosable не имеет ничего общего с CLR и в основном для пользовательского кода реализовать для выполнения дополнительных логики утилизации. Вызов Dissose () на объекте не будет освободить сам объект из памяти, хотя он может очень хорошо распознавать любые ресурсы, которые этот объект ссылается.

Я должен добавить, что в то время как то, что я сказал, это способ достижения этого, в 99,9999% приложений, которые вы никогда не должны звонить gc.collect () , потому что он часто разлагается производительность вашего приложения вместо того, чтобы улучшить его.

7
ответ дан 27 November 2019 в 18:14
поделиться

Невозможно уничтожить объект детерминированной моды. CLR определяет, когда помеченный объект будет восстановлен. Это означает, что, хотя вы можете пометить объект для утилизации и убедитесь, что управляемые и неуправляемые ресурсы вставляются на утилизацию (путем реализации IDSposable Pattern), фактическое время выпускается память, доставляется до CLR. Это отличается от C ++, где вы могли бы сделать что-то удалить, и он будет выпущен тогда.

2
ответ дан 27 November 2019 в 18:14
поделиться

Вы CAN Может заставить сборщик мусора запустить после переменной, который вы хотите уничтожить, выходит из системы, но вы обычно не хотите делать, поскольку сборщик мусора более эффективен, если сделать свою работу.

Принудительная сборка мусора может быть сделана с помощью gc.collect , но не делай этого. Через несколько лет как разработчик .NET, я никогда не нуждался в этом.

4
ответ дан 27 November 2019 в 18:14
поделиться
Другие вопросы по тегам:

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