Udostępnij za pośrednictwem


Zestawy kolekcjonowane dla dynamicznego generowania typów

Zestawy zbieralne to zestawy dynamiczne, które można zwolnić bez zwalniania domeny aplikacji, w której zostały utworzone. Wszystkie zarządzane i niezarządzane pamięci używane przez zestaw zbieralny i typy, które zawiera, można odzyskać. Informacje takie jak nazwa zestawu są usuwane z tabel wewnętrznych.

Aby włączyć zwalnianie, użyj flagi AssemblyBuilderAccess.RunAndCollect podczas tworzenia zestawu dynamicznego. Zestaw jest przejściowy (czyli nie można go zapisać) i podlega ograniczeniom opisanym w sekcji Ograniczenia dotyczące zestawów zbieralnych. Środowisko uruchomieniowe języka wspólnego (CLR) zwalnia zestaw zbieralny automatycznie po zwolnieniu wszystkich obiektów skojarzonych z zestawem. W każdym innym zakresie zestawy zbieralne są tworzone i używane w taki sam sposób jak inne zestawy dynamiczne.

Okres istnienia zestawów zbieralnych

Okres istnienia zestawu zbieralnego jest kontrolowany przez istnienie odwołań do typów, które zawiera, oraz obiektów utworzonych na podstawie tych typów. Środowisko uruchomieniowe języka wspólnego nie zwalnia zestawu, o ile istnieje co najmniej jeden z następujących typów (T jest dowolnym typem zdefiniowanym w zestawie):

  • Wystąpienie elementu T.

  • Wystąpienie tablicy .T

  • Wystąpienie typu ogólnego, które ma T jako jeden z argumentów typu. Obejmuje to kolekcje Togólne , nawet jeśli ta kolekcja jest pusta.

  • Wystąpienie elementu Type lub TypeBuilder , które reprezentuje T.

    Ważne

    Należy zwolnić wszystkie obiekty reprezentujące części zestawu. Element ModuleBuilder definiujący T przechowuje odwołanie do TypeBuilderobiektu , a AssemblyBuilder obiekt przechowuje odwołanie do ModuleBuilderobiektu , dlatego należy zwolnić odwołania do tych obiektów. Nawet istnienie obiektu LocalBuilder lub ILGenerator używanego w konstrukcji T zapobiega rozładowaniu.

  • Statyczne odwołanie do T innego dynamicznie zdefiniowanego typu T1 , który jest nadal osiągalny przez wykonanie kodu. Na przykład T1 może pochodzić z Tklasy lub T może być typem parametru T1w metodzie .

  • A ByRef do pola statycznego, które należy do T.

  • Element RuntimeTypeHandle, RuntimeFieldHandlelubRuntimeMethodHandle, który odwołuje się do T składnika lub .T

  • Wystąpienie dowolnego obiektu odbicia, którego można użyć pośrednio lub bezpośrednio w celu uzyskania dostępu do obiektu reprezentującego TypeTobiekt . Na przykład Type obiekt dla T elementu można uzyskać z typu tablicy, którego typ elementu to T, lub z typu ogólnego, który ma T jako argument typu.

  • Metoda M na stosie wywołań dowolnego wątku, gdzie M jest metodą lub metodą T na poziomie modułu, która jest zdefiniowana w zestawie.

  • Delegat do metody statycznej zdefiniowanej w module zestawu.

Jeśli tylko jeden element z tej listy istnieje tylko dla jednego typu lub jednej metody w zestawie, środowisko uruchomieniowe nie może zwolnić zestawu.

Uwaga

Środowisko uruchomieniowe nie zwalnia zestawu, dopóki finalizatory nie zostaną uruchomione dla wszystkich elementów na liście.

Do celów śledzenia okresu istnienia skonstruowany typ ogólny, taki jak List<int> (w języku C#) lub List(Of Integer) (w Visual Basic), który został utworzony i używany w generowaniu zestawu zbieralnego, jest uznawany za zdefiniowany w zestawie zawierającym definicję typu ogólnego lub w zestawie zawierającym definicję jednego z argumentów typu. Dokładny używany zestaw jest szczegółem implementacji i może ulec zmianie.

Ograniczenia dotyczące zestawów zbieralnych

Następujące ograniczenia dotyczą zestawów zbieralnych:

  • Odwołania statyczne

    Typy w zwykłym zestawie dynamicznym nie mogą zawierać statycznych odwołań do typów zdefiniowanych w zestawie zbieralnym. Jeśli na przykład zdefiniujesz zwykły typ, który dziedziczy z typu w zestawie zbieralnym NotSupportedException , zgłaszany jest wyjątek. Typ w zestawie zbieralnym może mieć statyczne odwołania do typu w innym zestawie zbieralnym, ale wydłuża to okres istnienia zestawu, do których odwołuje się zestaw, do okresu istnienia zestawu odwołującego się.

Następujące ograniczenia dotyczą zestawów zbieralnych w programie .NET Framework:

  • Międzyoperajności MODELU COM

    Interfejsy COM nie można zdefiniować w zestawie zbieralnym i nie można przekonwertować żadnych wystąpień typów w zestawie zbieralnym na obiekty COM. Typ w zestawie zbieralnym nie może służyć jako otoka wywoływana COM (CCW) lub wywoływana otoka środowiska uruchomieniowego (RCW). Jednak typy w zestawach zbieralnych mogą używać obiektów implementujących interfejsy COM.

  • Wywołanie platformy

    Metody, które mają DllImportAttribute atrybut, nie będą kompilowane po zadeklarowaniu ich w zestawie zbieralnym. Instrukcji OpCodes.Calli nie można używać w implementacji typu w zestawie zbieralnym, a takie typy nie mogą być rozdzielane do niezarządzanego kodu. Można jednak wywołać kod natywny przy użyciu punktu wejścia zadeklarowanego w zestawie, który nie jest zbieralny.

  • Marshaling

    Obiekty (w szczególności delegaty), które są zdefiniowane w zestawach zbieralnych, nie mogą być marshalled. Jest to ograniczenie dotyczące wszystkich typów emitowanych przejściowych.

  • Ładowanie zestawu

    Emocje emitowanie jonów jest jedynym mechanizmem obsługiwanym do ładowania zestawów zbieralnych. Nie można zwolnić zestawów ładowanych przy użyciu jakiejkolwiek innej formy ładowania zestawu.

  • Obiekty powiązane kontekstowo

    Zmienne statyczne kontekstowe nie są obsługiwane. Typy w zestawie zbieralnym nie mogą rozszerzać ContextBoundObjectelementu . Jednak kod w zestawach zbieralnych może używać obiektów powiązanych kontekstowo, które są zdefiniowane gdzie indziej.

  • Dane statyczne wątku

    Zmienne statyczne wątku nie są obsługiwane.

Następujące ograniczenia dotyczą zestawów zbieralnych w programach .NET Framework i .NET wcześniejszych niż .NET 9:

  • Pola statyczne z FixedAddressValueTypeAttribute

    Pola statyczne zdefiniowane w zestawach zbieralnych nie mogą mieć zastosowanego atrybutu FixedAddressValueTypeAttribute .

Zobacz też