Abfangen von Objekten in Java, die niedriger als die Benutzerklassenebene sind

8

Ich suche nach einem Ansatz, bei dem durch die Verwendung von Java-Agenten oder Instrumentenklassen (vorzugsweise etwas auf niedrigerer Ebene als Benutzerklassen) alle Objekte in JVM abgefangen werden ( new oder alternative Methoden zum Erstellen von Objekten) ähnliche Frage , die sich nicht auf den Java-Agenten oder etwas Niedrigeres konzentriert Benutzerklassen instrumentieren

    
Jigar Joshi 10.03.2016, 18:21
quelle

2 Antworten

14

Java-Objekte können auf verschiedene Arten erstellt werden.

  1. Aus Java-Code , wenn eine Java-Methode, entweder interpretiert oder kompiliert, eine der folgenden Bytecode-Anweisungen ausführt: new , newarray , anewarray , multianewarray .
  2. Aus nativem Code , wenn native Methoden, einschließlich derjenigen in der Standardklassenbibliothek, eine der folgenden JNI-Funktionen aufrufen: NewObject , NewObjectArray , NewStringUTF , NewDirectByteBuffer usw.
  3. Direkt aus VM-Laufzeit , wenn ein neues Objekt intern von JVM erstellt wird, z. B. als Antwort auf Object.clone() , Throwable.getStackTrace() , Class.getInterfaces() usw.

Leider gibt es keinen einzigen Punkt, an dem Sie Objekte aus all diesen Quellen sammeln können. Es gibt jedoch Mittel, um alle abzufangen.

  1. Aus Java instanziierte Objekte können von einer Instrumentation Agent. Der Agent muss einen ClassFileTransformer.html definieren, der den Bytecode scannt aller geladenen Klassen für Objekt erstellen Anweisungen und ändern Sie es.

    Hinweis: Sie müssen nicht alle new Anweisungen abfangen, stattdessen können Sie Object() Konstruktor instrumentieren. Aber Sie müssen immer noch Array-Zuweisungsanweisungen abfangen.

  2. JNI-Funktionen können vom JVMTI-Agenten abgefangen werden. Sie müssen Ihre eigenen nativen Hooks für NewObjectArray , NewStringUTF usw. definieren und dann die JNI-Funktionstabelle ersetzen. Einzelheiten finden Sie JVMTI Referenz .

  3. Objekte, die von der VM erstellt wurden, können von dem JVMTI Event Callback-Mechanismus . Das gewünschte Ereignis ist VMObjectAlloc .

    Hinweis: JVM speichert VMObjectAlloc event nicht für Objekte, die von Java oder JNI-Funktionen zugewiesen wurden.

Alle anderen Arten der Objektinstanzierung (Klonen, Reflektion, Deserialisierung) fallen in eine der obigen Kategorien.

Holen Sie sich JDK 8-Demos und Beispiele von Oracle Downloads von Java SE .
Es gibt einen Beispiel-JVMTI-Agenten für genau diese Frage.

Schau unter

  • jvmti/heapTracker
  • jvmti/hprof
apangin 10.03.2016, 21:25
quelle
2

Sie können sich diesen Open Source-Java-Agenten ansehen, der vom Devexperts-Team erstellt wurde Ссылка Es enthält nützliche Berichte, um zu ermitteln, wo Speicher zugewiesen ist. Aber wie ich weiß, fängt es keine neuen Objekte ab, die über JNI oder sun.misc.Unsafe.allocateInstance in der aktuellen Version erstellt wurden.

Es ist ein reiner Java-Agent, der Bytecode mit ASM manipuliert. Vor jeder Objektzuordnung fügt approf einen Methodenaufruf ein, der die Zuweisungsgröße und den Standortstapel (wo diese Zuordnung stattfindet) ablegt

    
Alex K 26.05.2016 10:25
quelle

Tags und Links