Stackalloc и типы значений

Я прочитал пример из старого поста Stackru о том, когда использовать stackalloc. Теперь этот пример меня немного озадачил:

public unsafe void DoSomeStuff()
{
    byte* unmanaged = stackalloc byte[100];
    byte[] managed = new byte[100];

    //Do stuff with the arrays

    //When this method exits, the unmanaged array gets immediately destroyed.
    //The managed array no longer has any handles to it, so it will get 
    //cleaned up the next time the garbage collector runs.
    //In the mean-time, it is still consuming memory and adding to the list of crap
    //the garbage collector needs to keep track of. If you're doing XNA dev on the
    //Xbox 360, this can be especially bad.
}

Теперь не стесняйтесь поправлять меня, если я не прав, так как я все еще начинающий в C# и программировании в целом. Но разве байтовые значения не являются типами? И не хранятся ли типы значений там, где они объявлены? Не означает ли это, что в этом примере managed также хранится в стеке, и, соответственно, когда этот кадр стека завершается и переходит к адресу вызова, память очищается автоматически и, следовательно, managed должны быть удалены так же, как unmanaged в этом примере?

2 ответа

Решение

Изолированные байты действительно являются типами значений, но массивы являются ссылочными типами. Указатель на managed здесь хранится в стеке, так же, как и весь unmanaged переменная, но память, используемая массивом, не восстанавливается, пока не будет запущен сборщик мусора.

Тип byte[] выглядит как stackalloc byte[100], но это представляет собой нечто совершенно иное. byte[] содержит ссылку на экземпляр объекта кучи, тип которого происходит от System.Arrayв то время как stackalloc byte[100] (и, в этом отношении fixed byte[100];) содержит 100 байт. Код, который ожидает что-то типа byte[] будет принимать только ссылку на объект кучи; он не будет принимать 100 байтов напрямую. Как и во всех ссылочных типах, System.Array экземпляр, на который существует какая-либо ссылка, гарантированно существует до тех пор, пока существует сама ссылка (если обнаруживается, что объект доступен только по слабым ссылкам, эти ссылки будут недействительными до того, как объект прекратит свое существование, чтобы поддержать этот инвариант). Если ни одна ссылка на массив не хранится где-либо за пределами текущего кадра стека, он перестает существовать после выхода из стекового кадра, но если ссылка хранится где-то еще, массив будет существовать столько же, сколько и любая ссылка.

Другие вопросы по тегам