9 Stimmen

constantPoolClass im Java-Heap?

Ich habe ein Java-Applet (ein echtes <APPLET>) geerbt, das nach etwa 4 Tagen Laufzeit eine OutOfMemory-Ausnahme auslöst. Es liegt in der Natur des Applets, dass die Leute es wirklich für lange Zeit offen lassen.

Nach fast zwei Tagen zeigt jmap -histo die größten Heap-Verbraucher an:

    num  #instances   #bytes  class name
    ---  ----------   ------  ----------
      1:      14277  7321880  <constantPoolKlass>
      2:      59626  5699968  <constMethodKlass>
      3:      14047  5479424  <constantPoolCacheKlass>
      4:      14277  5229744  <instanceKlassKlass>
      5:      59626  4778944  <methodKlass>
      6:      71026  3147624  <symbolKlass>

Das Problem ist, dass ich nicht verstehe, was diese Dinge sind. Es gibt mindestens zwei Dinge: constantPoolKlass+constantPoolCacheKlass+instanceKlassKlass scheinen zusammenzuhängen, ebenso wie constMethodKlass+methodKlass. Den Namen nach zu urteilen, scheinen sie mit einem Klassenlader zusammenzuhängen.

Wenn ich raten müsste, würde ich sagen, dass das Applet etwa 14.277 Objekte erzeugt hat, wobei jedes Objekt etwa 4 Methoden hat, also insgesamt etwa 59626 Methoden. Die Jmap-Ausgabe zeigt jedoch keine Klasse mit einer so großen Anzahl von Instanzen, und es sieht auch nicht so aus, als ob die Gesamtsumme der anderen Klassenobjekte 14277 beträgt. Vielleicht habe ich also falsche Vorstellungen davon, was diese Objekte tun. Kann mir das jemand erklären?

4voto

Tom Hawtin - tackline Punkte 142461

Ja, es sieht so aus, als ob Sie undichte Klassenlader haben. Wenn Sie nicht gerade Klassenlader in Ihrem eigenen Code erstellen (typischerweise durch URLClassLoader.newInstance oder XSLT), dann kann es mit dem Neuladen des Applets zusammenhängen (obwohl Sie normalerweise denselben Klassenlader zurückbekommen würden). Mögliche Ursachen für Lecks sind ThreadLocal, JDBC-Treiber und java.beans.

2voto

Michael Borgwardt Punkte 334642

Genau richtig - offensichtlich ein ClassLoader-Problem. Sehr seltsam, dass in einem Applet obwohl zu sehen; normalerweise ist es nur ein Problem mit appservers oder IDEs.

Es gibt zwei Möglichkeiten, dies zu debuggen: Entweder Sie besorgen sich einen echten Heap-Profiler, der Ihnen zeigen kann, wo die Daten Ihrer Runaway-Klasse referenziert werden, oder Sie patchen die API-Klassen wie hier beschrieben: http://www.onjava.com/pub/a/onjava/2004/06/30/classloader2.html?page=2

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X