Nach Diese Frage , die Standardgröße zur Bestimmung der Speichergröße eines Objekts in Java, ist java.lang.instrumentation. Nach einigen Nachforschungen sieht es so aus, als gäbe es keine Scala-spezifische Möglichkeit, dies zu erreichen, daher sollte der Java-Ansatz auch hier gelten.
Leider ist es für einen Scala-Programmierer ohne Java-Hintergrund nicht ganz einfach, diese Technik in Scala anzupassen. Meine Fragen sind:
Frage 1
Was genau passiert hier? Ich denke, der Grund, warum wir eine Klasse wie ObjectSizeFetcher
in eine separate JAR schreiben müssen, ist sicherzustellen, dass sie irgendwie vor dem eigentlichen Programm geladen wird, in dem wir sie benutzen wollen. Ich nehme an, es ist nicht möglich, Instrumente ohne den Eintrag Premain-Class
und den Parameter -javaagent:TheJarContainingObjectFetcher.jar
?
Frage 2
Gibt es eine einfache Möglichkeit, den gesamten Arbeitsablauf in SBT zu implementieren? Derzeit sehe ich nur eine etwas umständliche Lösung: Zuerst muss ich ein sekundäres SBT-Projekt einrichten, wo ich ObjectSizeFetcher
definiere und es in ein JAR packe. Bis jetzt habe ich nicht herausgefunden, wie man den Premain-Class
-Eintrag während des Packens automatisch in das JAR einfügt, also müsste ich das manuell lösen. Dann kann ich die resultierende JAR zu den lokalen Bibliotheken des Projekts hinzufügen, in dem ich getObjectSize
verwenden möchte. Für dieses Projekt muss ich nun fork in run
aktivieren und javaOptions in run += "-javaagent:TheJarContainingObjectFetcher.jar"
verwenden. Gibt es einen einfacheren (und weniger aufdringlichen) Arbeitsablauf, um die Instrumentierung innerhalb eines bestehenden SBT-Projekts schnell zu verwenden? Vielleicht kann ich SBT direkt über Premain-Class
sagen, um diese sekundäre JAR unnötig zu machen?
Frage 3
Würdest du eine völlig andere Möglichkeit empfehlen, die Speichernutzung eines Objekts in Scala zu bewerten?
Antwort 1: Ja, wenn Sie iinstrumentation möchten, müssen Sie eine Instanz erhalten. Sie können es wahrscheinlich nicht ohne Premain-Class und -javaagent erhalten.
Antwort 2: Sie können (und müssen möglicherweise) Classloader verwenden und ein sehr einfaches Bootstrap-Projekt erstellen (in Java oder in Scala mit Proguard). Dafür gibt es zwei Gründe:
Der erste Grund: Bequemlichkeit. Sie können java.net.URLClassLoader verwenden, um die Standard-Scala-Bibliothek und das Klassenverzeichnis Ihres Projekts einzuschließen. Sie müssen es beim Testen nicht mehr in JAR neu packen.
Der zweite Grund: JAR-Hölle zu verhindern. Sie wissen wahrscheinlich, dass Scala nicht binärkompatibel ist. Sie sollten auch wissen, dass der Java-Agent mit der Anwendung im selben Classloader geladen ist. Wenn der Classloader die Scala-Bibliothek enthält, kann die Anwendung nicht einfach eine andere Scala-Version verwenden.
Wenn jedoch der Java-Agent nicht direkt die Scala-Bibliothek verwendet (z. B. eine Bootstrap-Anwendung und den realen Agenten und seine Bibliotheken in einen anderen Klassenlader lädt), kann die instrumentierte Anwendung jede Scala-Bibliothek verwenden.
>Antwort 3: Ich würde wahrscheinlich auch Instrumentierung verwenden.
Antwort 3: Sie können sich ktoso/sbt-jol
ansehen, in der JOL (Java Object Layout) , dh die Analyse von Objektlayoutschemata in JVMs
Tags und Links scala java memory instrumentation sbt