2014-09-24 2 views
0

У меня есть программа, в которой я выделил массив int и хочу проверить, будет ли это сбор мусора после того, как я позвоню GC.Collect(). В этой программе я выделяю массив int array1 и сохраняю WeakReference, чтобы проверить, собирается ли он собирать мусор позже. У меня есть метод под названием procedure, который выделяет в нем новый локальный массив (array2) и присваивает array2 входному массиву temp, переданному по ссылке. Этот метод также присваивает слабые ссылки ref1 и ref2, чтобы хранить информацию о входе temp массив и array2. Когда я вызываю этот метод, я передаю ему array1, поэтому array1 становится равным array2. Как только я выхожу из метода, я вызываю GC.Collect() для принудительной сборки мусора. Отладчик сообщает ref1 и ref2 все еще имеет IsAlive свойство, равное true. ref3, который был создан в функции main и ссылки array1, сообщает, что IsAlive является false после сбора мусора, поэтому array1 уже был собран с мусором.2 слабые ссылки на один и тот же объект показать другую информацию

Не должны ref1, который ссылается array1, имеют IsAlive свойство, равное false, так же, как ref3 (который также ссылается array1) делает?

static WeakReference ref1; 
static WeakReference ref2; 
static WeakReference ref3; 

const int max_size = 10; 
public static void procedure(ref int []temp) 
{ 
    int[] array2 = new int[max_size]; 

    temp = array2; 

    for (int i = 0; i < max_size; i++) 
     array2[i] = i * 2; 

    ref1 = new WeakReference(temp); 
    ref2 = new WeakReference(array2); 
} 

static void Main(string[] args) 
{ 
    int []array1 = new int[max_size]; 

    ref3 = new WeakReference(array1); 

    procedure(ref array1); 
    //array1 = null; 
    GC.Collect(); 
} 
+1

ref1 ссылки array2. – krisdyson

ответ

2

Я думаю, что вы получили путать между вашими переменными и значений они указывают. В тот момент, когда вы вызываете GC.Collect(), array1, ref1, ref2 все указывают на массив, созданный в процедуре() (array1, являющийся единственной надежной ссылкой в ​​активном режиме).

Прослеживайте свой код вручную, отслеживая каждое значение (массив, созданный в процедуре(), массив, созданный в Main()), и какая переменная указывает на то, что в каждой точке.

Вы увидите, что в точке, где вы создаете две WeakReferences в процедуре(), temp и array2 указывают на одно и то же значение (массив, созданный тем же методом). WeakReference, созданный в Main(), будет единственной вещью, указывающей на массив, созданный в Main(), поскольку переменная array1 будет изменена, чтобы указать на другой массив процедурой() из-за ref.

+0

Я понял, что вы имеете в виду. Когда я изменил свой код, чтобы ref3 был создан после вызова процедуры() и был установлен в reference array1, который теперь равен array2, я получаю все 3 слабые ссылки, имеющие свойство IsAlive равным true. Мой другой вопрос - так как array2 был объявлен в процедуре и выходит за пределы области к тому времени, когда сбор мусора принудительно, разве это не сбор мусора? Все эти слабые ссылки имеют свойство IsAlive, равное true, поэтому то, что они ссылаются (array2 []), не было собрано в мусор. – user3623874

+0

Выполняя 'temp = array2;' в процедуре() (temp является аргументом ref), вы изменили переменную, объявленную в Main(), чтобы указать на массив, который сохраняет его. Ссылочные значения (например, массивы) никогда не «выходят за рамки» - только переменные, которые относятся к ним. –