2013-11-20 9 views
5

Ich sehe, dass es eine riesige Anzahl von int Array-Instanzen während der Java-Deserialisierung mit ObjectInputStream. Ich verstehe, dass dies aufgrund der Erstellung von Abhängigkeitsverfolgungsobjekten (java.io.ObjectInputStream$HandleTable$HandleList) ist. Wie ich es verstehe, werden sie verwendet, um ClassNotFoundException beim Lesen eines Objekts in "abhängige" Objekte zu übertragen.Sehr große Anzahl von int-Arrays während Java-Deserialisierung

Ich verstehe nicht die Notwendigkeit, diese Abhängigkeit von ClassNotFoundException über ein Zielobjekt zu verfolgen? Warum kann die Implementierung die Ausnahme nicht sofort auslösen, wenn ClassNotFoundException gefunden wird?

Bei der Deserialisierung in einer der Java-Anwendungen, in denen ich arbeite, gibt es signifikante Unebenheiten bei der transienten Speicherauslastung. Ich konnte die Spikes den int[] Instanzen zuordnen, nachdem ich ein Histogramm mit jmap erstellt habe.

Ich versuche festzustellen, ob die Beendigung des Deserialisierungsprozesses bei der Begegnung mit ClassNotFoundException in Ordnung sein sollte. In diesem Fall möchte ich den ObjectInputStream ändern und die modifizierte Klasse im Bootstrap-Klassenpfad verwenden.

Ich weiß, dass die "Einträge" von HandleTable unbedingt erforderlich sind, um zuvor gelesene Objekte in abhängige Objekte zu verdrahten, die später aus dem Stream gelesen werden. Nur um zu klären, ging es um die Bedeutung von java.io.ObjectInputStream$HandleTable$HandleList, die ich nicht verstehe.

Jede Einsicht wird sehr geschätzt.

Danke,
Raja.

Antwort

1

Es verfolgt Objekte zum Zweck zirkuläre Referenzen zu lösen und um sicherzustellen, dass zwei Objekte A und B, die vor Serialisierung auf dasselbe Objekt C nicht Punkt nach Deserialisierung an zwei getrennten Instanzen von C zeigen. Ohne Verweise auf, wenn die Objekthierarchie von A deserialisiert wird, erstellt es eine Instanz von C, und beim Deserialisieren der B-Objekthierarchie würde es eine weitere separate Instanz von C erstellen. Es hat wenig mit ClassNotFoundException zu tun.

Das Beste, was Sie tun können, ist ObjectInputStreams wegzuwerfen, sobald Sie mit der Deserialisierung eines "Graphs" von Objekten fertig sind, anstatt es für viele Objekte wiederzuverwenden.

+0

Rückverweise werden in 'java.io.ObjectInputStream $ HandleTable.entries' nachverfolgt. Und ja, sie werden für das, was du gesagt hast, benötigt. Meine Frage bezieht sich jedoch auf 'java.io.ObjectInputStream $ HandleTable.deps', welches ein Array von HandleList ist. Wenn Sie den Code von 'ObjectInputStream' durchsehen, geschieht dies für die Abhängigkeitsüberwachung von ClassNotFoundException. Das 'entries'-Array sollte ausreichen, um nach Reference und Wire zu suchen,' deps' wäre für diesen Zweck nicht erforderlich. Ist das nicht wahr? –

+0

Ja, es sieht so aus, als ob die '' deps'' für die Verbreitung von ClassNotFoundException ausgelegt sind. Wenn Sie 100% sicher sind, dass all Ihre Klassen zur Deserialisierungszeit vorhanden sind und Sie diesen Aufwand eliminieren möchten, kopieren Sie die Quelle '' ObjectInputStream'' in Ihre eigene '' MyObjectInputStream''-Klasse und rippen Sie das Abhängigkeits-Tracking aus. – brettw

+0

Auch wenn es eine 'ClassNotFoundException' im geänderten Code gibt, möchte ich die Ausnahme sofort werfen und propagieren. Damit ist das Scheitern immer noch evident. –