2017-01-14 4 views
1

Как видно из названия, меня интересует, когда статические классы загружаются в память в .NET, C# в частности. Я предполагаю, что он похож на this question на Java и this question относительно статических методов, так как он загружается при первом использовании. Кроме того, как только он находится в памяти, он остается там до тех пор, пока приложение не завершится или не будет очищено, когда сборщик мусора придет, чтобы очистить класс, который его использовал?Когда статические классы в .NET загружены в память?

Я понимаю небольшой объем памяти, которую использует статический класс, не очень важно в мире компьютеров с 8 стандартами ОЗУ, но всегда интересно знать внутренности.

Edit:

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

public static class Contraption 
{ 
    public static string SomeString = "Some String"; 
    public static string AnotherString = "Another String"; 
} 

public class Processor 
{ 
    public void Process(List<SomeClass> items) 
    { 
     foreach(var item in items) 
     { 
      if(item.Name == Contraption.SomeString) 
      { 
       //do something 
      } 
      if(item.Name == Contraption.AnotherString) 
      { 
       //do something 
      } 
     } 
    } 
} 

ответ

2

Что касается статической инициализации полей, важным моментом является использование static constructor. CLR имеет компонент загрузчика класса, который загружает класс (информацию метаданных) и запрашивает выделение памяти из диспетчера памяти, поскольку они используются в программе. Загрузка метаданных - одноразовая работа, после чего она просто запрашивает память по необходимости.

Как было понято в обсуждении, переменные статического класса загружаются при первом использовании класса в любом месте и им присваивается память, но с использованием статической конструктор может гарантировать, что они инициализируются как первое, когда вызывается загрузчик классов, его одноразовый вызов, который может выполнять инициализацию всех статических переменных в классе, это даже предшествует первой политике использования, так как это когда CLR (mscoree.dll) - компоненты загружаются для данной программы.

Статический конструктор не вызывается после того, как первый раз при любых обстоятельствах (кроме перезапуска программы), даже если есть исключения, его довольно широко используется, а также статические переменные могут быть собраны путем установки их в качестве null

+0

так что статические не выделяют память во время компиляции? но во время выполнения, когда он впервые использовался? где он хранится? STACK или HEAP? –

1

Я предполагаю, что вы имеете в виду поля в статических классах (или статические поля в нестатических классах). Они будут инициализированы до первого использования. Это описано в C# спецификация:

10.4.5.1 Статическое поле инициализации

статическое поле инициализаторы переменных одного класса соответствуют последовательности заданий, которые выполняются в текстовом порядке, в котором они появляются в декларации класса. Если в классе существует статический конструктор (раздел 10.11), выполнение инициализаторов статического поля происходит непосредственно перед выполнением этого статического конструктора. В противном случае инициализаторы статического поля выполняются в зависящее от реализации время до первого использования статического поля этого класса.

Статические члены класса считается корнями Garbage Collection и все всегда достижимый.

Вы можете заставить объекты быть восстановленными путем сброса статического члена null или другого объекта:

public static class Foo 
{ 
    public static object Bar = new object(); 
} 

// somewhere later 
Foo.Bar = null; 
// the object can be collected now. 
+0

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

+0

Что означает 'новая строка (« Моя первая строка здесь »)? Предположим? – PetSerAl

+0

@PetSerAl Существует некоторая дополнительная сложность, связанная с литеральными строками и интернированием строк. использование 'new string()' предназначено для обхода этого. Я изменил его как объект вместо того, чтобы сделать его менее запутанным. – MarcinJuraszek

0

Статические переменные сохраняются в течение времени жизни AppDomain, и в .NET, вы можете иметь несколько AppDoamins за приложение. Хотя большую часть времени это всего лишь один AppDomain для каждого приложения, а другие AppDomains в основном созданы для плагинов для песочницы.

https://msdn.microsoft.com/en-us/library/2bh4z9hs(v=vs.110).aspx