2017-05-18 2 views
0

Ich verwende derzeit eine Bibliothek von SWIG in .NET. Die Dokumentation für diese Bibliothek scheint keine Informationen darüber zu enthalten, ob oder welche der erstellten Klassen entsorgt werden müssen. Ich habe auch Diskussionen in anderen Foren darüber gesehen, dass ich Code hinzufügen muss, um untergeordnete Elemente zu entfernen, die ich in der Quelle für diese Bibliothek nicht sehe. Obendrein enthalten die Beispielprojekte und Tests für die Bibliothek keine using s, und die Objekte, die sie erstellen, sind auch nicht verfügbar.Muss ich SWIG-generierte Objekte entsorgen?

Also, muss ich das "durchschnittliche" SWIG-Objekt entsorgen? Es scheint, dass sie alle Standard-Destruktoren haben, die das Objekt im zugrundeliegenden C++ löschen. Wenn das der Fall ist, kann ich sie einfach wie jedes andere Objekt behandeln und vom Garbage Collector behandeln lassen (abgesehen von Dingen, die verhindern würden, dass der Garbage Collector sie richtig behandelt, wie zirkuläre Referenzen und andere klassische Speicherlecks). Es wäre scheiße, alle Aufrufe/Objekte mit irgendeiner Art von Entsorgungskontext oder etwas in diese Bibliothek einzubinden.

+1

Kreisreferenzen verhindern nicht, dass Objekte entsorgt werden. – Servy

+0

Hat SWIG dem C# -Objekt Finalizer hinzugefügt? Wenn nicht, haben Sie wahrscheinlich einen Speicherverlust, da der GC nicht garantiert, dass Dispose in allen Fällen aufgerufen wird. –

+0

Es hängt davon ab, wie SWIG zum Erstellen des Wrappers verwendet wurde. Es gibt viele Möglichkeiten zum Einwickeln von Objekten, die Sie manuell entsorgen müssen.Zur gleichen Zeit, wie @JoelLucsy erklärt, kann der Wrapper so erstellt werden, dass der generierte Code Finalizer enthält, was eine korrekte GC gewährleistet. –

Antwort

0

Angesichts der Antworten in den Kommentaren scheint es, dass es in meinem Fall insgesamt nicht notwendig ist. SWIG erzeugte korrekte Finalizer, die die Dispose-Funktion aufrufen. Es ist möglich, dass die Verfügungsfunktion in der SWIG-Definition nicht korrekt definiert ist, aber wenn dies der Fall ist, hilft die manuelle Entsorgung sowieso nicht.

Edit: Während die anfängliche Behauptung, dass die Entsorgung der Objekte nicht notwendig ist, gibt es einen Fall, wo es nützlich sein kann.

Betrachten wir den Fall, wo Sie eine Sammelobjekt durch SWIG ausgesetzt haben: Collection Darüber hinaus haben Sie eine ‚item‘ Objekt der Sammlung im Besitz: Collection collection = new Collection(1, 2, 3); Item item = collection.Get(1); // c is now available for collection, as there are no longer any P/invokes nor references to it item.GetValue(); // Can possibly throw AccessViolationException if collection has been collected // based on how it cleans up its items.

: Item

Wenn Sie dies tun sollten

Um dies zu verhindern, müssen Sie verhindern, dass collection finalisiert/entsorgt wird, bis nach alle item s verwendet werden. Dies kann in ein paar Möglichkeiten:

  • Nutzen GC.KeepAlive() am Ende alle Verwendungen von item s. Z.B.

    item.GetValue();

    GC.KeepAlive(collection);

  • Nutzen Sie die IDisposable Muster determinis Entsorgung des übergeordneten Objekts zu gewährleisten. Z.B.

using(Collection collection = new Collection(1, 2, 3)) { Item item = collection.Get(1); item.GetValue(); }

So manuelle Entsorgung oder das IDisposable Muster verwendet, ist nicht notwendig per se, aber es kann Ihre Nutzung der nicht verwalteten Objekte ist sicher, konsistent und klar stellen Sie sicher nützlich sein, dass.

Verwandte Themen