2016-09-30 2 views
2

Beim Extrahieren eines Heapdumps habe ich festgestellt, dass viele Objekte auf die Fertigstellung warten, die meisten davon sind Instanzen aus Bibliotheken wie jdbc-Verbindungen und so weiter.java.lang.ref.Finalizer OutOfMemory Nach Speichererhöhung

Wissen, dass diese Instanzen in der Warteschlange grundsätzlich Klassen sind, die implementiert finalize(), warum würden sie einfach nicht finalisiert werden?

Vor ein paar Tagen hob ich die Erinnerung an solche Instanz. Anfangs hatte es 1 GB mit neuer Generation auf 256 MB eingestellt (-Xmx1g -XX:NewSize=256m -XX:MaxNewSize=256m). Als wir einige starke Caching-Funktionalitäten hinzugefügt haben, haben wir den Speicher, der dieser Instanz zugewiesen wurde, auf 3 GB erhöht (-Xmx3G -XX:NewSize=512m -XX:MaxNewSize=512m). Von diesem Moment an beginnen wir einige Erinnerungen zu sehen. Ich habe eine Menge java.lang.ref.Finalizer und Objekte gefunden, die auf Finalisierung warten.

Wie könnte dies miteinander verwandt sein? Kann es sogar verwandt sein?

Antwort

3

Warum würden sie einfach nicht finalisiert werden?

Einige Komponenten dauern länger, um alles abzuschließen, was IO betrifft. JDBC-Verbindungen sind relativ schwergewichtige Netzwerkressourcen, so dass sie noch länger dauern.

Ich schlage vor, Sie verwenden einen Verbindungspool (die meisten JDBC-Bibliotheken haben sie eingebaut) Auf diese Weise erstellen/zerstören Sie sie nicht die ganze Zeit.

Hinweis: zur Verdeutlichung 1Gb = 1 Gig-Bit oder 128 MB (Mega-Bytes) 256 mb ist 256 Milli-Bits oder etwa 1/4 eines Bits. -XX:NewSize=512m ist 512 MB nicht 256 MB. und -XX:MaxNewSize=512 würde nicht funktionieren, da es nur 512 Bytes ist, höchstwahrscheinlich verwendet man -XX:MaxNewSize=512m

3Gb 3 Giga-Bit aber vorausgesetzt, Sie 3 GB gemeint ist nicht -Xmx1G, die 1 GB oder 8 GB.

+0

Sie haben Recht, ich aktualisierte die Einheiten auf meine Frage –

+0

was ich bin ein bisschen neugierig ist, wie das sein würde, warum taucht dieses Problem mit dem 'finalize()' nur nach der Speicheränderung auf, würde dies mit der Ration verbunden sein, die ich zwischen der neuen Generation und der alten Generation verwendet habe? –

+0

@FranciscoSpaeth Die Anwendung, die die zu finalisierenden Ressourcen generiert, ist langsamer, wenn weniger Arbeitsspeicher zur Verfügung steht. Es könnte multi-threaded sein. Wenn Sie mehr Speicher bereitstellen, können mehr Ressourcen erstellt werden, die bereinigt werden müssen. Der Finalizer mit einem einzelnen Thread kann jedoch nicht mithalten, sodass er zum Engpass wird. Kurz gesagt, wenn Sie ein Bit schneller machen, verschieben Sie das Leistungsproblem woanders und brechen es möglicherweise dabei. –

1

Object.finalize() wird vom Garbage Collector im letzten Schritt der Bereinigung aufgerufen. Der GC wird in regelmäßigen Abständen ausgeführt (abhängig davon, welchen GC Sie verwenden, wenn es sich bei 7 und 8 um CMS handelt, oder G1, wenn Sie dies so konfiguriert haben). Wenn Sie viele Objekte in "Warten auf Finalisierung" haben, bedeutet das möglicherweise, dass Sie einen großen Heap und ausreichend Speicher haben, den der GC nicht ausführen muss (CMS wahrscheinlich, da G1 sehr viel häufiger Mikro-Cleanups ausführt).

hinzufügen GC Tracing Ihrer JVM-Startparameter und überwachen, wie oft es läuft: -XX: + PrintGCDetails -XX: + PrintGCTimeStamps Siehe: http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html

Wenn Sie viele kleine Objekte mit einem Haufen> 1 GB verwenden Sie Vielleicht möchten Sie den G1-Garbage-Collector in Betracht ziehen, da er für eine solche Aufgabe besser geeignet ist und nicht das CMS-Verhalten "Stoppt die Welt" aufweist.