Stack
stack
- это блок памяти для хранения local variables
и parameters
. Стек логически растет и сжимается при входе и выходе из функции.
Рассмотрим следующий метод:
public static int Factorial (int x)
{
if (x == 0)
{
return 1;
}
return x * Factorial (x - 1);
}
Этот метод рекурсивный, то есть он вызывает сам себя. Каждый раз, когда вводится метод, в стеке выделяется новое значение int , а при каждом выходе из метода значение int освобождается .
Heap
- Куча - это блок памяти, в котором находится
objects
(т. Е. reference-type instances
). Всякий раз, когда создается новый объект, он размещается в куче, и возвращается ссылка на этот объект. Во время выполнения программы куча начинает заполняться при создании новых объектов. Среда выполнения имеет сборщик мусора, который периодически освобождает объекты из кучи, поэтому ваша программа не запускается Out Of Memory
. Объект может быть освобожден, если на него не ссылается ничего, что само по себе alive
.
- В куче также хранится
static fields
. В отличие от объектов, размещенных в куче (которые могут собираться мусором), these live until the application domain is torn down
.
Рассмотрим следующий метод:
using System;
using System.Text;
class Test
{
public static void Main()
{
StringBuilder ref1 = new StringBuilder ("object1");
Console.WriteLine (ref1);
// The StringBuilder referenced by ref1 is now eligible for GC.
StringBuilder ref2 = new StringBuilder ("object2");
StringBuilder ref3 = ref2;
// The StringBuilder referenced by ref2 is NOT yet eligible for GC.
Console.WriteLine (ref3); // object2
}
}
В приведенном выше примере мы начинаем с создания объекта StringBuilder, на который ссылается переменная ref1, а затем записываем его содержимое. Затем этот объект StringBuilder сразу же может быть использован для сборки мусора, поскольку впоследствии его никто не использует. Затем мы создаем еще один StringBuilder, на который ссылается переменная ref2, и копируем эту ссылку в ref3. Несмотря на то, что ref2 не используется после этой точки, ref3 поддерживает тот же объект StringBuilder, что гарантирует, что он не сможет быть собран до тех пор, пока мы не закончили использовать ref3.
Экземпляры типа значения (и ссылки на объекты) живут везде, где была переменная
объявлен. Если экземпляр был объявлен как поле внутри типа класса или как элемент массива, этот экземпляр находится в куче.