2016-05-08 13 views
1

Also schreibe ich meine eigene 3D-Engine. Ich behalte Objekte, die ich aus einer OBJ-Datei geladen habe, innerhalb einer Array-Liste. Das Problem ist, wenn ich das Objekt aus der Liste entferne, wird es nicht Müll gesammelt. Es kann immer noch irgendwo im Code referenziert werden, aber es ist ein Schmerz im Hals zu suchen. Also habe ich mich gefragt, ob es eine Möglichkeit gibt, das Objekt zu sperren, wenn ich es lösche, so dass es einen Fehler gibt, wenn etwas versucht, darauf zuzugreifen.

Ein High-Poly-Mesh kann im Speicher bis zu einigen hundert Megabytes aufnehmen.

Danke. (Ich möchte den Code nicht posten, weil er ziemlich kolossal ist)Wie absichtlich Objekt für Garbage Collection. (Java)

Antwort

-1

Wenn Sie einen Container haben, fügen Sie ein Objekt hinzu und entfernen Sie dann das Objekt. Sie haben nun keinen Verweis mehr auf dieses Objekt.

Wenn Sie wirklich besorgt über die Referenz sind, oder wenn Sie Kopien davon gemacht haben, dann nur implizit = null sie.

"der Fehler" geworfen würde der jetzt Nullzeiger sein, sollten Sie noch einen Verweis darauf haben. (Aber wenn Sie es wirklich entfernen möchten, sollten Sie nicht)

+0

Das Objekt ist nicht wirklich in irgendeinem Container. Wenn es erstellt wird, wird es in der ArrayList gespeichert. Mir ist aufgefallen, dass es einen Verweis auf ein Netz gibt, das auch eine Referenz am Objekt hat. Es kann wegen der Referenzschleife nicht gesammelt werden. –

+0

@JackLe Jede lesbar moderne JVM, die häufig verwendet wird, hat einen Garbage Collector, der Referenzschleifen verarbeiten kann. – hexafraction

+0

@JackLe Garbage Collection behandelt Zyklen per Definition. Java hat das von Anfang an getan. – EJP

0

Sie können ein Objekt nicht aus dem Speicher entfernen, wenn es noch referenziert wird.

Das Beste, was Sie tun können, ist den internen Zustand zu entfernen oder zu minimieren, wenn das Objekt so strukturiert ist. Beispielsweise können Sie clear() für Sammlungen aufrufen, und das wird alle Elemente aus der Auflistung entfernen, wodurch es viel kleiner wird. In Ihrem Fall, ich nehme an, Sie könnten eine "invalidate" -Methode hinzufügen, die so etwas macht (obwohl es wahrscheinlich ein komisches Design ist, wäre es wirklich besser herauszufinden, wo das Objekt noch benutzt wird und warum).

1

Dies kann mit einem zusätzlichen Grad der Dereferenzierung gelöst werden. Anstatt Ihre BigObject in einer Sammlung zu speichern, speichert eine „Hülle“ für das Objekt, und fügen Sie einen release() Betrieb den einzigen Hinweis auf das eigentliche Objekt löschen:

interface MyInterface { 
    void usefulOperation(); 
} 
class VeryBigObject implements MyInterface { 
    public void usefulOperation() { 
     ... 
    } 
} 
class BigObjectEnvelope implements MyInterface { 
    private MyInterface inner = new VeryBigObject(); 
    public void usefulOperation() { 
     inner.usefulOperation(); 
    } 
    public void release() { 
     inner = null; 
    } 
} 

Machen Sie eine Sammlung von BigObjectEnvelope Objekten, und sie verwenden durch ihre MyInterface Schnittstelle. Wenn Sie mit dem Objekt fertig sind, rufen Sie release() darauf. Selbst wenn Sie an anderen Stellen andere Referenzen auf BigObjectEnvelope haben, würde das Aufrufen von usefulOperation() eine Ausnahme auslösen.

+0

Sehr interessante Idee. Es ist, als würde man die Tombstone-Technik manuell implementieren. Ich werde es ausprobieren –