2016-09-13 4 views
0

Ich konnte ObjectHeap.iterateObjectsOfKlass (mit Hilfe von SA) aufrufen, um alle Objekte einer bestimmten Klasse zu erhalten. Das Ergebnis ist genau das, was ich erwartet habe, aber die Leistung ist nicht.HotSpot Servicepersonal iterateObjectsOfKlass() ist zu langsam

Es dauerte> 800 Sekunden, um mein Ergebnis zu erhalten, währenddessen die Ziel-VM angehalten wurde. Der Ziel-VM-Heap beträgt etwa 2 GB. Ich weiß iterateObjectsOfKlass wird iterateExact anrufen.

Meine Frage ist: diese iterate/traverse den gesamten Heap nur um Objekte für 1 Klasse zu erhalten? Ich bin enttäuscht, da ich mit einer einzelnen Klasse erwarte, dass das Ergebnis innerhalb von 10 Sekunden zurückkehrt.

+1

Gute Frage. In der Ursprungsform war dies jedoch nicht ganz klar (insbesondere für Personen, die mit dem Serviceability Agent nicht vertraut sind). – apangin

+0

Sicher, es muss den gesamten Heap scannen, um alle Objekte aller Art zu finden. Die Art des Filters hat keinen Einfluss auf diese Tatsache. Wie haben Sie erwartet, dass es funktioniert? – Holger

+0

Ich habe nicht erwartet, dass der gesamte Heap gescannt wird. Ich dachte, dass, seit eine Klasse angegeben wurde, iterateObjectsOfKlass in seiner Objektabfrage operativ sein wird. - Matthias. Danke @Holger –

Antwort

4

HotSpot Serviceability Agent ist wirklich leistungsstarke Technologie, aber in der Tat sehr langsam. Ich habe erklärt, wie es in this answer funktioniert.

JVM hat keine Möglichkeit, alle Instanzen der spezifischen Klasse schnell zu finden. Also, ja, es muss den gesamten Heap scannen. Um den Speicher eines fremden Prozesses zu lesen, verwendet SA außerdem einen Systemaufruf von ptrace für jedes einzelne Datenwort. Deshalb ist es so langsam.

Sie haben mehrere Möglichkeiten, schneller zu scannen Heap:

  1. eine coredump eines ausländischen Prozess erstellen und dann SA Werkzeug gegen das coredump laufen. Dies ist viel schneller, als den Speicher eines ausgesetzten Prozesses zu lesen. Siehe related question.
  2. Injektion eines JVMTI Agenten in einen laufenden Prozess mit Dynamic Attach mechanism. Der Agent kann den Heap einer lokalen JVM mithilfe der Funktion IterateOverInstancesOfClass scannen. Dies wird im Vergleich zu SA dramatisch schneller sein, weil es nur aus dem gleichen Prozess ohne irgendwelche Systemaufrufe oder was auch immer lesen wird. Ich glaube, dass es nur ein paar Sekunden dauern wird, bis ein 2-GB-Heap verfügbar ist.
+1

Vielen Dank für Ihre gute Antwort! @apangin –