Каков жизненный цикл объекта .NET?
Каков жизненный цикл объекта для объекта в .NET?
Из того, что я понимаю, это:
- Объект создан - вызванный конструктор (если он существует)
- Используемые методы/свойства/поля
- Объект уничтожен - Dispose вызываемый (если он существует)
- Деструктор, вызываемый GC в некоторой точке
Ответы
Ответ 1
Dispose не вызывается автоматически; вам нужно вызвать его или использовать используемый блок, например.
using(Stream s = File.OpenRead(@"c:\temp\somefile.txt"))
// Do something with s
Финализатор только вызывается GC, если он существует. Наличие финализатора заставляет ваш класс собираться за 2 шага; сначала объект помещается в очередь финализатора, затем вызывается финализатор и объект собирается. Объекты без финализаторов напрямую собираются.
Руководством является то, что Dispose избавляется от управляемых и неуправляемых ресурсов, а финализатор только очищает неуправляемые ресурсы. Когда метод Dispose освободил неуправляемые ресурсы, он может вызвать GC.SuppressFinalize, чтобы объект не жил долго, чтобы его помещали в очередь финализатора. См. MSDN для правильного образца шаблона удаления.
Ответ 2
Так же, как и кромка края... вы можете создавать объекты без использования ctor вообще:
class Foo {
public Foo() {
message += "; ctor";
}
string message = "init";
public string Message { get { return message; } }
}
static class Program {
static void Main() {
Foo foo = new Foo();
Console.WriteLine(foo.Message); // "init; ctor"
Foo bar = (Foo)System.Runtime.Serialization.FormatterServices
.GetSafeUninitializedObject(typeof(Foo));
Console.WriteLine(bar.Message); // null
}
}
Ответ 3
Вот шаги, которые я знаю:
- загрузить сборку
- выполнить статические инициализаторы
- "новый" вызов:
- выделить память
- выполнить нестатические инициализаторы
- выполнить конструктор
- экземпляр теперь готов к использованию
- после того, как последняя ссылка на объект исчезла: если объект не имеет финализатора, он теперь готов к сборке; если объект имеет финализатор, он помещается в очередь финализатора.
- (необязательно) объекты из очереди финализатора имеют свой финализатор, вызываемый в специальном потоке; если по-прежнему нет ссылки из приложения на объект, он также становится теперь подходящим для сбора мусора.
- сборщик мусора освобождает память
Как уже указывали другие, Dispose()
должен быть вызван пользователем, так как среда выполнения не будет действовать на него.
Ответ 4
Здесь - подробный описатель вопроса. Во-первых, Dispose не вызывается во время выполнения, вы должны называть его самостоятельно. Также нет деструкторов, но финализаторы: если объект переопределяет метод Finalized, он вызывается, когда объект больше не доступен для приложения. Может случиться так, что при завершении объект снова становится доступным (например, сохраняет ссылку на себя в глобальном объекте), поэтому он возвращается к шагу 2 вашей модели. Существуют также методы в объекте GC, которые позволяют пользователю контролировать завершение объекта.
Ответ 5
Точка о конструкторе:
Каждый класс имеет один, поскольку один будет сгенерирован компилятором, если вы его не закодируете сами.
И первое, что это делает (если не указано иное), - это вызов ctor этого родительского типа.
Ответ 6
0) Если Static Constructor существует в Object, он вызывается в первый раз, и объект этого типа создается или ссылается
Ответ 7
Вот примерный класс, который использует всю информацию, доступную в приведенных здесь статьях. Я уже много часов тестировал, и это самое лучшее для меня.
/*********************************
* Author: Theofanis Pantelides *
* Date: 23 Jun 2009 *
*********************************/
using System;
using System.IO;
public class MyClass : IDisposable
{
String oFile;
Stream oStream;
public MyClass(String _File)
{
oStream = File.OpenRead(oFile = _File);
// Initialize
}
~MyClass()
{
this.Dispose();
// Destruct
}
public void doSomething()
{
// do Whatever it is you are trying to do
}
#region IDisposable Members
/// <summary>
/// Dispose all resources used by instance of class
/// and update Garbage Collector information
/// </summary>
public void Dispose()
{
if (oStream != null)
{
oStream.Dispose(); // Dispose using built in functions
GC.SuppressFinalize(oStream); // No need for Garbage Collector
}
oStream = null; // Nullify it.
}
#endregion
}
Использование:
using(MyClass mc = new MyClass(@"c:\temp\somefile.txt"))
{
mc.doSomething();
}
Вы даже можете использовать одно и то же объявление дважды, поскольку оно не существует вне "использования".
using(MyClass mc = new MyClass(@"c:\temp\somefile.txt"))
{
mc.doSomething();
}
using(MyClass mc = new MyClass(@"c:\temp\somefile.txt"))
{
mc.doSomething();
}
Ответ 8
Жизненный цикл объекта
Создание объекта. Для создания нового объекта используется ключевое слово новое.
- Выделен блок памяти. Этот блок памяти достаточно велик, чтобы удерживать объект. (CLR обрабатывает выделение памяти для управляемых объектов)
- Блок памяти преобразуется в объект. Объект инициализируется. (Вы можете управлять этим шагом, выполнив конструктор)
Уничтожение объекта. Вы используете уничтожение для восстановления любых ресурсов, используемых этим объектом.
- Объект очищается; например, путем выпуска любых неуправляемых ресурсов, используемых приложением, таких как дескрипторы файлов и подключения к базе данных. (Вы можете управлять этим шагом, внедряя деструктор.)
- Память, используемая объектом, исправлена.
CLR обрабатывает выпуск памяти, используемой управляемыми объектами; однако, если вы используете неуправляемые объекты, вам может потребоваться вручную освободить память, используемую этими элементами.
Ответ 9
Эта статья о сборке мусора должна помочь вам лучше понять
Ответ 10
В С# инициализаторы членов вызывается перед конструктором в VB.NET, они вызывается после конструктора.
Время выполнения не гарантирует вызов Finalize
вообще.
Dispose и Finalize предназначен только для очистки неуправляемых ресурсов. Попытка очистки управляемых ресурсов в финализаторе, например. вызов Dispose на внутренних членах приведет вас к беде, потому что они, возможно, уже были завершены.
Мне нравится держать вещи простыми и просто использовать финализатор для обнаружения и регистрации неприятного сообщения об ошибке, указывающего разработчику исправить код. Попытка выяснить, является ли безопасным выполнение работы Dispose
, как предполагалось, слишком легко ошибаться и обычно не стоит проводить циклы.