Dziś znowu zaprezentuję mało znane słowo kluczowe w języku c# – stackalloc. Najpierw jednak kilka słów przypomnienia na temat alokacji pamięci w .NET. Generalnie mamy dwa typy obiektów: reference type oraz value type. Typy referencyjne to klasy, z kolei value type to Enum, Integer, Float itp. Klasy alokowane są na stercie (heap), która zarządzana jest przez Garbage Collector. Value Type deklarowane są z kolei na zwykłym stosie. Wyjątkiem jest sytuacja w której value type jest składową reference type (np. pole w klasie) – wtedy będzie umieszczone na stercie
Domyślnie tablica danych umieszczana jest na stercie, a wskaźnik na nią na stosie. Można to zmienić wykorzystując słowo stackalloc:
unsafe { int* array = stackalloc int[100]; }
Tablica array zostanie w całości zadeklarowana na stosie. Wiąże się z tym kilka korzyści:
-
Nie musimy martwić się, że GC zmieni adres obiektu – słowo kluczowe fixed jest całkowicie niepotrzebne. Adres na stercie jest zawsze taki sam. Czasami lepiej zadeklarować tablicę na stosie niż na stercie z fixed.
-
Zwalnianie obiektów na stosie jest dużo szybsze – wystarczy, że metoda skończy swoje wykonywane a cały stos (zawierający parametry wejściowe itp.) zostanie po prostu wyczyszczony. Koniec problemów z fragmentacją, pinning itp.
Stos oczywiście nadaję się wyłącznie do małych i tymczasowych obiektów. Tak jak ze słowem fixed, rzadko w praktyce zdarza się konieczność jego zastosowania. Microsoft jednak jak widać dostarcza kilku “niskopoziomowych” mechanizmów na wszelki wypadek. Czasami aplikacja, która głównie wykonuje zarządzany kod, potrzebuje wykonać coś bardzo skomplikowanego i wtedy możemy właśnie skorzystać z sekcji unsafe.