Kann Garbage Collection mit expliziter Speicherverwaltung koexistieren?

8

Nehmen wir zum Beispiel an, dass ein Schlüsselwort "delete" in C # 4 enthalten sein soll. Wäre es möglich, zu garantieren, dass Sie keine wilden Zeiger hätten, aber aufgrund des Verweises immer noch auf den Müllsammler vertrauen könnten System?

Der einzige Weg, den ich sehen könnte, ist, wenn ein Verweis anstelle von Verweisen auf Speicherorte ein Index für eine Tabelle von Zeigern auf tatsächliche Objekte ist. Ich bin mir jedoch sicher, dass es eine Bedingung geben würde, wo das brechen würde, und es wäre möglich, die Typsicherheit zu unterbrechen / hängende Zeiger zu haben.

EDIT: Ich spreche nicht nur über .net. Ich habe nur C # als Beispiel verwendet.

    
TraumaPony 25.10.2008, 12:01
quelle

9 Antworten

3

Sie können - gewissermaßen: machen Sie Ihr Objekt Einweg, und dann entsorgen Sie es selbst.

Durch ein manuelles Löschen wird die Speicherleistung in einer verwalteten Umgebung wahrscheinlich nicht verbessert. Es kann mit nicht verwalteten Ressourcen helfen, worum es sich handelt.

Ich hätte lieber Einwegobjekte implementiert und konsumiert. Ich habe keine konsistente, vollständige Idee, wie dies aussehen sollte, aber die Verwaltung nicht verwalteter Ressourcen ist ein umfassender Schmerz unter .NET.

Eine Idee zum Implementieren von Löschen: lösche Tags ein Objekt zum manuellen Löschen. Beim nächsten Speicherbereinigungszyklus wird das Objekt entfernt und alle Verweise darauf werden auf null gesetzt.

Es klingt zunächst cool (zumindest für mich), aber ich bezweifle, dass es nützlich wäre. Dies ist auch nicht besonders sicher, z. Ein anderer Thread ist möglicherweise damit beschäftigt, eine Mitgliedsmethode für dieses Objekt auszuführen. Eine solche Methode muss z. beim Zugriff auf Objektdaten.

    
peterchen 25.10.2008 12:27
quelle
2

Bei der Garbage-Collection bleibt es so lange aktiv, wie Sie eine Referenz auf das Objekt haben. Mit manuellem Löschen können Sie das nicht garantieren.

Beispiel (Pseudocode):

%Vor%

Um nur kurz zu sein, die Kombination von manueller Speicherverwaltung und Garbage Collection vereitelt den Zweck von GC. Außerdem, warum? Und wenn Sie wirklich Kontrolle haben wollen, verwenden Sie C ++ und nicht C #. ; -).

    
Toon Krijthe 25.10.2008 12:13
quelle
1

Das Beste, was Sie bekommen könnten, wäre eine Aufteilung in zwei "Hemisphären", wo eine Hemisphäre verwaltet wird und die Abwesenheit von herabhängenden Zeigern garantieren kann. Die andere Hemisphäre hat explizites Speichermanagement und gibt keine Garantien. Diese beiden können koexistieren, aber nein, du kannst der zweiten Hemisphäre deine starken Garantien nicht geben. Sie können nur alle Zeiger verfolgen. Wenn einer gelöscht wird, könnten alle anderen Zeiger auf dieselbe Instanz auf Null gesetzt werden. Es ist unnötig zu sagen, dass dies ziemlich teuer ist. Dein Tisch würde helfen, aber andere Kosten einführen (doppelte Indirektion).

    
Konrad Rudolph 25.10.2008 12:14
quelle
0

Chris Sells diskutierte das auch auf .NET Rocks. Ich denke, es war während seines ersten Auftretens, aber das Thema könnte in späteren Interviews noch einmal besprochen worden sein.

Ссылка

    
Rob Windsor 25.10.2008 14:43
quelle
0

Meine erste Reaktion war: Warum nicht? Ich kann mir nicht vorstellen, dass du etwas so Unklares tun willst, wie einen unreferenzierten Brocken auf dem Haufen liegen zu lassen, um ihn später wieder zu finden. Als ob ein Vier-Byte-Zeiger auf den Heap zu viel wäre, um diesen Teil zu verfolgen.

Das Problem besteht also nicht darin, unreferenzierten Speicher zuzuweisen, sondern absichtlich den Speicher noch als Referenz zu verwenden. Da die Garbage-Collection die Funktion hat, den Speicher irgendwann frei zu machen, scheint es, als müssten wir einfach eine alternative Folge von Anweisungen aufrufen können, um diesen bestimmten Teil des Speichers zu entfernen.

Aber das Problem liegt hier:

%Vor%

Worauf zeigen t und u ? In einem strengen Bezugssystem sollten t und u null sein. Das bedeutet, dass Sie nicht nur die Referenz zählen , sondern auch verfolgen müssen.

Allerdings kann ich sehen, dass Sie sollte mit s an diesem Punkt in Ihrem Code getan werden. So kann junk den Verweis auf null setzen und mit einer Art Prioritätscode an den Sweeper übergeben. Der GC könnte für einen begrenzten Lauf aktiviert werden, und der Speicher wird nur freigegeben, wenn er nicht erreichbar ist. Wir können also nichts, was jemand codiert hat, explizit wieder freigeben. Aber Wenn s die einzige Referenz ist, wird der Chunk freigegeben.

Also, ich denke, es würde nur mit einer begrenzten Einhaltung der expliziten Seite funktionieren.

    
Axeman 25.10.2008 23:04
quelle
0

In nicht verwalteten Sprachen wie C ++ ist es möglich und bereits implementiert. Grundsätzlich implementieren oder verwenden Sie einen vorhandenen Garbage Collector: Wenn Sie die manuelle Speicherverwaltung wünschen, rufen Sie neu auf und löschen wie üblich. Wenn Sie Garbage Collection durchführen möchten, rufen Sie GC_MALLOC oder die Funktion oder das Makro für Ihren Garbage Collector auf. p>

Siehe Ссылка für ein Beispiel.

Da Sie C # als Beispiel verwendet haben, haben Sie vielleicht nur daran gedacht, die manuelle Speicherverwaltung in einer verwalteten Sprache zu implementieren, aber dies soll Ihnen zeigen, dass das Gegenteil möglich ist.

    
Asik 15.08.2009 00:10
quelle
0

Wenn die Semantik von delete für die Referenz eines Objekts alle anderen Verweise, die auf dieses Objekt verweisen, auf null setzen würde, könnten Sie dies mit zwei Ebenen der Indirektion tun (1 mehr als Sie andeuten). Beachten Sie, dass während das zugrunde liegende Objekt zerstört wird, eine feste Menge an Informationen (genug, um eine Referenz zu halten) auf dem Heap gespeichert werden muss.

Alle Referenzen, die ein Benutzer verwendet, würden eine versteckte Referenz (die vermutlich in einem Heap lebt) auf das reale Objekt verweisen. Wenn Sie eine Operation für das Objekt ausführen (z. B. eine Methode aufrufen oder sich auf ihre Identität verlassen, z. B. den Operator == verwenden), würde die Referenz, die der Programmierer verwendet, die versteckte Referenz dereferenzieren. Beim Löschen eines Objekts würde das tatsächliche Objekt aus dem Heap entfernt und die versteckte Referenz auf Null gesetzt. Somit würden die Verweisprogrammierer das Ergebnis auf null setzen sehen.

Es wäre die Aufgabe des GC, diese verborgenen Referenzen zu bereinigen.

    
Thomas Eding 30.01.2010 04:14
quelle
0

Dies würde in Situationen mit langlebigen Objekten helfen. Garbage Collection funktioniert gut, wenn Objekte für kurze Zeiträume verwendet und schnell wieder referenziert werden. Das Problem ist, wenn einige Objekte für eine lange Zeit leben. Die einzige Möglichkeit, sie zu bereinigen, besteht in der Durchführung einer ressourcenintensiven Speicherbereinigung.

In diesen Situationen würden die Dinge viel einfacher funktionieren, wenn es eine Möglichkeit gäbe, Objekte explizit zu löschen, oder zumindest eine Möglichkeit, einen Graphen von Objekten zurück in die Generation 0 zu verschieben.

    
user191535 16.08.2010 08:48
quelle
0

Ja ... aber mit etwas Missbrauch.

C # kann ein wenig missbraucht werden, um das zu ermöglichen. Wenn Sie bereit sind, mit der Klasse Marshal , StructLayout und unsafe code herumzuspielen, könnten Sie Ihren eigenen manuellen Speichermanager schreiben.

Hier finden Sie eine Demonstration des Konzepts: Schreiben eines Handbuchs Speichermanager in C # .

    
Liran 19.12.2011 19:11
quelle