Где CLR хранит статические классы?

Короткий ответ... это зависит.

  1. Статические определенные локальные переменные не теряют свое значение между вызовами функции. Другими словами, они - глобальные переменные, но ограниченный по объему к локальной функции они определяются в.

  2. Статические глобальные переменные не видимы за пределами файла C, в котором они определяются.

  3. Статические функции не видимы за пределами файла C, в котором они определяются.

7
задан Athiwat Chunlakhan 1 March 2016 в 10:11
поделиться

2 ответа

Я думаю, вы путаете классы с , где живет память, с тем, как удерживается память. Когда вы создаете экземпляр нормального класса, память этого экземпляра находится в куче. Ссылка на этот экземпляр может находиться в объекте в куче (если вы установите для него переменную-член внутри другого экземпляра объекта); или переменная стека (если вы объявили переменную объекту внутри метода или передали ее в вызов функции), или она может быть в списке глобальных корней (если это статическая ссылка, например ссылка Singleton).

Невозможно создать статический класс. Нигде нет «ссылки» на класс (кроме информации о типе). Его методы - это просто функции, загружаемые в память, когда CLR загружает сборку. Вы можете создать делегат, который указывает на один из этих методов, но он также не ссылается на экземпляр класса. Это просто указатель на функцию.

Например, посмотрите на этот код:

class ObjectWrapper
{
    Object obj = new Object();
}

static void Main(string[] args)
{
    ObjectWrapper wrapper = new ObjectWrapper();
    ...
}

Метод Main создает экземпляр класса ObjectWrapper. Этот экземпляр находится в куче.

Внутри экземпляра ObjectWrapper есть экземпляр класса Object, который живет в куче. Ссылка на этот класс находится внутри экземпляра, поэтому я думаю, вы могли бы думать об этой ссылке как о «живущей в куче».

Теперь сравните это со следующим кодом:

class Singleton
{
    static readonly instance = new Singleton();
}

Экземпляр объекта Singleton продолжает существовать. куча тоже. Однако ссылка является статической. Он поддерживается CLR в списке глобальных или «корневых» ссылок.

Теперь посмотрим на этот статический класс:

class ObjectWrapper
{
    Object obj = new Object();
}

static class HelperMethods
{
    static int DoSomethingUseful(ObjectWrapper wrapper1)
    {
        ObjectWraper wrapper2 = wrapper1;
        // code here
    }
}

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

16
ответ дан 6 December 2019 в 08:16
поделиться

Чтобы дать вам простой ответ, статические классы «хранятся» в так называемой куче загрузчика. Куча загрузчика - это особые исцеления, не связанные с GC, которые имеют чрезвычайно предсказуемую и строгую скорость роста. Когда запускается приложение .NET, фактически создается несколько доменов приложений. В дополнение к основному домену приложения существуют системные и общие домены приложений, которые содержат системные пространства имен и mscorelib, специальные кучи (например, кучи загрузчика) и саму среду CLR.

Для получения более подробного объяснения прочтите следующее Статья в журнале MSDN:

Изучите внутреннюю структуру .NET Framework, чтобы увидеть, как среда CLR создает объекты среды выполнения

Несмотря на то, что она была создана несколько лет назад, она все еще применима. (Однако я не могу сказать, сильно ли изменилась .NET 4.0.)

6
ответ дан 6 December 2019 в 08:16
поделиться
Другие вопросы по тегам:

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