I have never heard of a premain
and I feel a little stupid to ask but the answer of this post suggests to run it in order to get the Instrumentation
object.
But how does that function get called or how do I make it getting called?
package playground; import java.lang.instrument.Instrumentation; public class ObjectSizeFetcher { private static Instrumentation instrumentation; public static void premain(String args, Instrumentation inst) { instrumentation = inst; } public static long getObjectSize(Object o) { return instrumentation.getObjectSize(o); } }
Manifest Attributes. The following manifest attributes are defined for an agent JAR file: Premain-Class. When an agent is specified at JVM launch time this attribute specifies the agent class.
In general, a java agent is just a specially crafted jar file. It utilizes the Instrumentation API that the JVM provides to alter existing byte-code that is loaded in a JVM. For an agent to work, we need to define two methods: premain – will statically load the agent using -javaagent parameter at JVM startup.
This class provides services needed to instrument Java programming language code. Instrumentation is the addition of byte-codes to methods for the purpose of gathering data to be utilized by tools. Since the changes are purely additive, these tools do not modify application state or behavior.
To create a successful javaagent we'll need four things: an agent class, some meta-information to tell the JVM what capabilities to give to our agent class, a way to make the JVM load the . jar with the agent before it starts minding the application's business and a coffee.
The premain
is a mechanism associated with the java.lang.instrument
package, used for loading "Agents" which make byte-code changes in Java programs.
The mechanism is explained in the java.lang.instrument
documentation.
The gist of it is that the "agent" is deployed in a jar, and that jar has a special entry in its manifest, that tells the instrumentation package where to look for the premain method. The source you quoted is supposed to be a simple agent.
Minimal runnable example
GitHub upstream: https://github.com/cirosantilli/java-cheat/tree/d73d2786cad458973a6b46bc98b9faabae65f3e1/instrument
META-INF/MANIFEST.MF
Premain-Class: Sizeof
Sizeof.java
import java.lang.instrument.Instrumentation; final public class Sizeof { private static Instrumentation instrumentation; public static void premain(String args, Instrumentation inst) { instrumentation = inst; } public static long sizeof(Object o) { return instrumentation.getObjectSize(o); } }
Main.java
final public class Main { public static void main(String [] args) { System.out.println("Object"); System.out.println(Sizeof.sizeof(new Object())); System.out.println("/\"\""); System.out.println(Sizeof.sizeof("")); System.out.println("/\"abc\""); System.out.println(Sizeof.sizeof("abc")); System.out.println("int[0]"); System.out.println(Sizeof.sizeof(new int[0])); System.out.println("int[10]"); System.out.println(Sizeof.sizeof(new int[10])); class OneInt { public int i; } System.out.println("OneInt"); System.out.println(Sizeof.sizeof(new OneInt())); class TwoInts { public int i; public int j; } System.out.println("TwoInts"); System.out.println(Sizeof.sizeof(new TwoInts())); class IntArray0 { int[] i = new int[0]; } System.out.println("IntArray0"); System.out.println(Sizeof.sizeof(new IntArray0())); class IntArray10 { int[] i = new int[10]; } System.out.println("IntArray10"); System.out.println(Sizeof.sizeof(new IntArray10())); } }
Makefile
all: javac *.java jar -cfm Sizeof.jar META-INF/MANIFEST.MF Sizeof.class java -ea -javaagent:Sizeof.jar Main
Sample output:
Object 16 /"" 24 /"abc" 24 int[0] 16 int[10] 56 OneInt 16 TwoInts 24 IntArray0 16 IntArray10 16
Tested in Ubuntu 16.10, Java HotSpot 1.8.0_92.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With