Find the size of an object in Java


Reading time: 30 minutes | Coding time: 10 minutes

Unlike languages such as C/ C++ which has a function sizeof() to get memory size of any object, Java has no such direct method. It is, still, possible to get the size of an object in Java using its instrumentation package.

Instrumentation package in Java is used to instrument any Java code and get details of it. It is a common analysis technique which is natively supported in Java using the package. In short, in this technique, we insert code to the original code to track changes and performance. As changes are inserted, the original code remains unimpacted and hence, it is a good analysis tool.

To import this package, we need to use this:

import java.lang.instrument.Instrumentation;

We will create a Java class named ObjectSize to implement this. The first step is to create an instrumentation object as a private member of the class as follows:

private static Instrumentation instrumentation;

We need to use premain mechanism of the package. In short, it allows "agents" (specific methods) to get loaded and make bytecode changes in Java code. It uses jar which makes an entry in its manifest file pointing to the premain function. For our example, we will define a simple premain function as follows:

public static void premain(String args, Instrumentation inst)
{
     instrumentation = inst;
}

Following this, we can use the getObjectSize() method of the package. It will insert bytecode in your code which will calculate size of any object. There are several approaches in which this is achieved in Java and the simplest way to to capture the total memory used at different stages to calculate this information.

We can create a sizeof() function as follows:

public static long sizeof(Object o) 
{
    return instrumentation.getObjectSize(o);
}

Complete code (save in a file named 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);
    }
}

We shall create a manifest file in the project root directory with location and name (META-INF/MANIFEST.MF) as follows:

Premain-Class: Sizeof

We can create the jar file of our class using the following command in the command line:

jar -cfm Sizeof.jar META-INF/MANIFEST.MF Sizeof.class

Sizeof.jar will be created.

Once done, we can write any Java code say in file code.java and use this function to get the size of any object directly:

Sizeof.sizeof(myobject);

The code should be compiled and run as follows:

javac code.java
java -ea -javaagent:Sizeof.jar code

In this example, code is the name of our class.

Example

In this example, we will create a simple program to calculate the size of int, float and string using the above utility we created:

Complete code:

final public class code 
{
    public static void main(String [] args) 
    {
        int a; 
        float b;
        String c;
        System.out.println("size of int: " + Sizeof.sizeof(a));
        System.out.println("size of float: " + Sizeof.sizeof(b));
        System.out.println("size of string: " + Sizeof.sizeof(c));
    }
}

Output:

size of int: 16
size of float: 16
size of string: 16 

Note that the above sizes are same as we have not initialized the variables and hence, all three variables are for memory address.

Now, we shall initialize the variables and then check the size:

final public class code 
{
    public static void main(String [] args) 
    {
        int a = 1; 
        float b = 1.0;
        String c = "opengenus";
        System.out.println("size of int: " + Sizeof.sizeof(a));
        System.out.println("size of float: " + Sizeof.sizeof(b));
        System.out.println("size of string: " + Sizeof.sizeof(c));
    }
}

Output:

size of int: 48
size of float: 48
size of string: 88

Explanation:

For int, size = memory + int size = 16 + 32 = 48

For float, size = memory + float size = 16 + 32 = 48

For string, size = memory + character size * number of characters
= 16 + 8 * 9 = 16 + 72 = 88

Let us use an user defined object having an array of 10 integers as a member variable:

final public class code 
{
    class userobject
    {
        int data[] = new int[10];
    }
    public static void main(String [] args) 
    {
        System.out.println("size of user object: " + Sizeof.sizeof(new userobject()));
    }
}

Output:

size of user object: 16

This is 16 bits as it is only storing the address of the object as there is no user defined constructor.

Same is the case if we use an default object using the Object class of Java:

new Object()

Complete code:

final public class code 
{
    public static void main(String [] args) 
    {
        System.out.println("size of object: " + Sizeof.sizeof(new Object()));
    }
}

Output:

size of object: 16

Hence, any object has two components for memory:

  • 16 bits for memory (depends on system)
  • memory for the data initialized

Similarly, you can use this method to calculate the size of any object in Java instantly.