4 Stimmen

Garbage Collection für C#- und C++/CLI-Objekte

Ich untersuche derzeit die Verwendung von C++/CLI, um die Lücke zwischen verwaltetem C# und nativem, nicht verwaltetem C++-Code zu schließen. Ein besonderes Problem, das ich zu lösen suche, ist die Konvertierung von Datentypen, die in C# und C++ unterschiedlich sind.

Während ich mich über die Verwendung eines solchen Überbrückungskonzepts und die damit verbundenen Leistungsauswirkungen informierte, fragte ich mich, wie die Garbage Collection funktionieren würde. Insbesondere, wie der Garbage Collector die Bereinigung von Objekten handhaben würde, die auf einer der beiden Seiten erstellt wurden, wenn sie auf der "anderen Seite" referenziert/zerstört werden.

Bislang habe ich verschiedene Artikel und Fragen in Foren gelesen über StackOverflow y MSDN Das hat mich zu der Annahme geführt, dass der Garbage Collector in beiden Codetypen arbeiten sollte, wenn er im selben Prozess ausgeführt wird - d. h. wenn ein Objekt in C# erstellt und an die C++/CLI-Brücke übergeben wurde, würde es erst dann gesammelt werden, wenn die Referenzen auf beiden Seiten nicht mehr verwendet werden.

Meine Frage besteht in diesem Fall aus drei Teilen:

  1. Gehe ich recht in der Annahme, dass der Garbage Collector über beide Teile des Codes (C# und C++/CLI) funktioniert, wenn er im selben Prozess ausgeführt wird?
  2. In Bezug auf 1: Wie funktioniert es unter diesen Umständen (insbesondere im Hinblick auf die Bereinigung von Objekten, auf die beide Codebasen verweisen).
  3. Gibt es Vorschläge, wie man die Aktivität des Garbage Collectors überwachen kann - z.B. durch das Schreiben von Tests, die prüfen, wann Garbage Collection stattfindet; oder durch ein Programm, das den Garbage Collector selbst überwacht.

Ich habe bereits etwas von einem Verständnis, wie der Garbage Collector im Allgemeinen funktioniert, so dass meine Fragen hier spezifisch für das folgende Szenario sind:

Komponenten

  • Baugruppe A - (geschrieben in C#)
  • Baugruppe B - (geschrieben in C++/CLI)

Ausführung des Programms

  1. Objekt O wird erstellt in Montage A .
  2. Objekt O wird an eine Funktion innerhalb von Montage B .
  3. Verweis auf das Objekt O en Montage A freigegeben wird.
  4. Montage B hält den Verweis auf das Objekt O .
  5. Die Ausführung wird beendet (z. B. durch Programmende).
  6. Montage B gibt den Verweis auf das Objekt frei O .

Vielen Dank im Voraus für alle Gedanken zu dieser Frage. Lassen Sie mich wissen, ob weitere Informationen erforderlich sind oder ob etwas nicht klar genug ist.

EDIT

Wie gewünscht, habe ich ein grobes Beispiel für das Szenario geschrieben, das ich zu beschreiben versuche. Die C# y C++/CLI Code kann auf PasteBin gefunden werden.

4voto

Jon Hanna Punkte 106367

Wenn der Code tatsächlich ausgeführt wird, wird nichts davon C# oder C++/CLI sein. Alles wird IL aus der C# und C++/CLI und Maschinencode aus dem nativen Code sein, mit dem Sie interagieren.

Sie könnten also einen Teil Ihrer Frage umformulieren in:

  • Baugruppe A - (IL und wir wissen nicht, in welcher Sprache sie geschrieben wurde)
  • Baugruppe B - (IL und wir wissen nicht, in welcher Sprache sie geschrieben wurde)

Von den verwalteten Objekten werden alle nach den gleichen Regeln garbage collected, es sei denn, Sie verwenden einen Mechanismus, um dies zu verhindern (GC.KeepAlive). Alle könnten im Speicher verschoben werden, es sei denn, Sie pinnen sie (weil Sie Adressen an nicht verwalteten Code weitergeben).

Der .NET Profiler gibt Ihnen einige Informationen über die Garbage Collection, ebenso wie die Collection Counts im Performance Monitor.

1voto

Haris Hasan Punkte 29356

Gehe ich recht in der Annahme, dass die Teile des Codes (C# und C++/CLI) funktioniert, wenn er im selben Prozess ausgeführt wird?

Ja, ein einziger Garbage Collector arbeitet innerhalb eines Prozesses für beide (C# und Managed C++). Wenn es innerhalb eines Prozesses Code gibt, der unter verschiedenen CLR-Versionen läuft, gibt es für jede CLR-Version eine andere Instanz des GC.

Zu 1: Wie funktioniert es in einem solchen Fall (insbesondere in Bezug auf die Bereinigung von Objekten, auf die beide Codebasen verweisen).

Ich denke, für GC spielt es keine Rolle, ob es sich um verwalteten C#- oder C++/CLI-Code handelt (beachten Sie, dass GC nur C#- und verwalteten C++-Code und nicht natives C++ verwaltet). Sie wird auf ihre eigene Weise arbeiten, ohne zu berücksichtigen, welche Art von Code zugrunde liegt. Was das Freigeben von Speicher angeht, so wird GC dies immer dann tun, wenn ein Objekt nicht mehr referenziert werden kann. Solange also etwas auf eine Variable verweist, wird sie unabhängig von der Assembly nicht eingesammelt. Bei nativem C++-Code müssen Sie jeden dynamisch zugewiesenen Speicher manuell freigeben.

Gibt es Vorschläge, wie man die Aktivitäten der Collector zu überwachen - z.B. durch das Schreiben von Tests, die prüfen, wann Garbage Collection stattfindet; oder ein Programm, das den Garbage Collector selbst überwacht.

Sie können Tools wie .Net Profiler zur Überwachung verwenden. Werfen Sie auch einen Blick auf Benachrichtigungen über die Müllabfuhr

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X