Hello, I hope you guys are fascinated with my blog post. If yes, do send me your comments or do subscribe and if not, I am open to accept your feedback and recommendations.
This blog is about understanding the differences between primitive types and wrapper classes. It will also help you to understand the structure and the memory consumptions made by each one of them.
Let us start with what is wrapper classes.
A wrapper class is a class whose object wraps or contains primitive type value. The main reason to create wrapper classes is their usage in Collection Framework as collections can only accept objects.
The decision of what to use totally depends on what kind of performance you need for your application, how much available memory do you have, and what default values should be handled.
Primitive types are stored on the stack. Hence, it is accessed faster compared to heap memory. The reference types are objects and they are stored on heap memory. Therefore, having some overhead when it comes to performance.
When we instantiate a wrapper class, it occupies much more memory than it requires to hold the primitive value. For example, if we create an object of Integer wrapper class, the actual int value will be 1:4 of the total size of the object. The remaining is used to hold the metadata. The metadata includes the following:
- Class — A pointer to the type of the class. In the above example, it is the Integer class (Size:32bits)
- Flags — A collection of flags that describes the state of an object, including the hashcode of an object and the shape of an object ie it is an array or not (Size:32bits)
- Locks — The synchronization information of an object, including if it is synchronized currently (Size:32bits)
Therefore, the total size of an Integer wrapper class object is 128 bits.
The decision must be towards primitive types unless you have enough reasons to make it a wrapper class object.
- Method parameters can be of primitive type as you are always expecting a value.
- Defining local variables as primitive types.
Let us try to understand with the help of an example. But, before going into the actual program, let us first create a jar file which will help you to get the size of an object.
In Java 5, an interface Instrumentation was introduced to estimate the size of an object. Instrumentation is the addition of byte codes to methods for the purpose of gathering data to be utilized by the tools. Since these changes are purely additive, these changes do not modify application state or behavior. Examples of such tools include monitoring agents, profilers, coverage analyzers, and event loggers.
There are two ways to obtain an instance of the Instrumentation interface.
- When a JVM is launched in a way that indicates an agent class. In that case, Instrumentation implementation is passed to the premain method of the agent class.
- When a JVM provides a mechanism to start agents sometime after the JVM is launched. In that case, an Instrumentation instance is passed to the agent method of the agent code.
In this example, we are going to use the first approach. In order to call Instrumentation.getObjectSize(Object) to get object size, we need to access the instance of the Instrumentation first. For that, we have to create an instrumentation agent. An instrumentation agent will provide a premain method which will be first invoked by the JVM when using instrumentation. Besides that, we need to expose a static method to be able to access Instrumentation.getObjectSize(Object).
Following is the code for InstrumentatinonAgent.
Before we create a JAR for this agent, we need to make sure that a simple metafile, MANIFEST.MF included in it. Add the following line in the metafile and remember to add a space after Premain-Class: and press “enter” at the end of the line.
Create InstrumentationAgent jar using the following commands
- javac Memory\InstrumentationAgent.java
- jar cmf MANIFEST.MF InstrumentationAgent.jar Memory\InstrumentationAgent.class
Let us now create a sample class that will make use of this agent that we just created.
Now we need to include -javaagent option with the path to the agent JAR when running our application.
- java -javaagent:”InstrumentationAgent.jar” WrapperClass
As you can see in the output, the memory consumption of wrapper classes is much higher compared to primitive types.
That’s all from this blog. I hope you guys liked it. Keep sending me your comments and feedback. But wait, do read about primitive collections. Yes, you heard it right. There are many third-party libraries available and of course “The Valhalla Project” by OpenJDK.
Oh yes, before I end this blog, I would like to tell you guys that one of my friends is writing blogs on Design patterns. Do read and follow him on