Was ist der Unterschied zwischen verwaltetem Heap und nativem Heap in der c # -Anwendung?

8

Von diesem Ссылка

  1. Verwaltet: Für verwaltete Anwendungen sammelt der Profiler standardmäßig nur verwaltete Heap-Informationen. Die Profilerstellung für verwaltete Heapspeicher erfolgt durch Erfassen einer Reihe von CLR ETW-Ereignissen im Profiler.
  2. Nativ: Für native Anwendungen sammelt der Profiler nur native Heap-Informationen. Zum Sammeln von nativen Heap-Informationen aktivieren wir Stack-Tracing und die Sammlung von Heap-Traces (ETW), die sehr ausführlich sind und große DiagSession-Dateien erstellen.

Meine Frage ist In meinem c # -Programm (ich habe nur c # -Code mit Xaml-Dateien), welche Arten von Objekt wird zu verwalteten Heap und welche Arten zu native Heap geht? Und wie kann ich die maximale Größe jedes Heapspeichers angeben, wenn meine Anwendung ausgeführt wird? Ich nehme an, GC läuft nur auf verwalteten Heap, ist das richtig?

    
michael 09.06.2015, 04:40
quelle

1 Antwort

5

Wenn Sie ein Objekt mit dem neuen Operator in C # (oder dem entsprechenden Operator in einer anderen CLR-Sprache) erstellen, ordnet die .NET-Laufzeit Speicher im "verwalteten Heap" zu (einfach ein von der .NET-Laufzeitumgebung verwaltetes Heap) Müllsammler). Dies ist in Wirklichkeit eine von zwei Haufen - eine für Objekte mit einer Größe von weniger als 85K und die andere für Objekte, die größer sind als diese (große Arrays und dergleichen). Wie auch immer, wenn ein solches Objekt zugewiesen wird, erhalten Sie keinen echten Zeiger zurück, der die Adresse des zugewiesenen Speicherplatzes beschreibt, wie Sie es in nativem Code tun würden. Was Sie zurückbekommen, ist ein "Handle", das eine Indirektion zu dieser Speicheradresse darstellt. Diese Indirektion existiert, weil sich der tatsächliche Speicherort ändern kann, wenn der GC den Heap sammelt und komprimiert.

Wenn Sie mit nicht verwaltetem / nativem Code kommunizieren möchten, der einen Zeiger erwartet, müssen Sie jedoch Zeiger und keine Handles verwenden. .NET bietet zwei Methoden zum Konvertieren eines .NET-Handles in einen unformatierten Zeiger, der an nicht verwalteten Code übergeben werden kann.

  1. Ordnen Sie dem NT-Speicher (oder nativem oder nicht verwaltetem Speicher) Speicher zu, indem Sie Marshal.AllocHGlobal oder Marshal.AllocCoTaskMem und verwenden Sie entweder einen festen Block oder IntPtr.ToInt32 / ToInt64 , um den zugrunde liegenden Zeiger zu erhalten. Stellen Sie sicher, dass Sie entweder Marshal aufrufen .FreeHGlobal / Marshal.FreeCoTaskMem selbst oder dass der nicht verwaltete Code den Speicher korrekt freigibt (FreeAlloc / CoTaskMemFree unter Windows).
  2. Wenn Ihre Daten blitable sind (was wahrscheinlich ist Wenn Sie mit nativem Code zusammenarbeiten, können Sie diese verwalteten Daten einfach mit GCHandle.Alloc und rufen Sie dann mit dem von GCHandle.AddrOfPinnedObject , Freigabe der Pinning (mit GCHandle.Free ), wenn Sie fertig sind. Sie können auch die tatsächliche zugrunde liegende Zeigeradresse eines verwalteten Objekts abrufen und vorübergehend in einem " behoben " in C # blockieren.

Ich hoffe, das hilft!

    
Ani 09.06.2015, 07:10
quelle

Tags und Links