How Big Is an Object Reference in Java and Precisely What Information Does It Contain

How big is an object reference?

A object or array reference occupies one 32 bit word (4 bytes) on a 32 bit JVM or Davlik VM. A null takes the same space as a reference. (It has to, because a null has to fit in a reference-typed slot; i.e. instance field, local variable, etc.)

On the other hand, an object occupies a minimum of 2 32 bit words (8 bytes), and an array occupies a minimum of 3 32 bit words (12 bytes). The actual size depends on the number and kinds of fields for an object, and on the number and kind of elements for an array.


For a 64 bit JVM, the size of a reference is 64 bits, unless you have configured the JVM to use compressed pointers:

-XX:+UseCompressedOops Enables the use of compressed pointers (object references represented as 32 bit offsets instead of 64-bit pointers) for optimized 64-bit performance with Java heap sizes less than 32gb.


This is the nub of your question, I think.

Before determining the size of the hash table, I wanted to know how much memory would it consume in order not to exagerate.

If you allocate a HashMap or Hashtable with a large initial size, the majority of the space will be occupied by the hash array. This is an array of references, so the size will be 3 + initialSize 32 bit words. It is unlikely that this will be significant ... unless you get your size estimate drastically wrong.

However, I think you are probably worrying unnecessarily about performance. If you are storing objects in a default allocated HashMap or Hashtable, the class will automatically resize the hash table as it gets larger. So, provided that your objects have a decent hash function (not too slow, not hashing everything to a small number of values) the hash table should not be a direct CPU performance concern.

Java: How much memory a reference implies?

It's not specified by the language or JVM spec. However, it's generally accepted that any sane implementation will be 4 bytes on a 32-bit machines and between 4 and 8 bytes (depending on compressed pointer settings, etc.) on a 64-bit machine.

How to test how many bytes an object reference use in Java?

Taking the question literally, on most JVMs, all references on 32-bit JVMs take 4 bytes, one 64-bit JVMs, a reference takes 8 bytes unless -XX:+UseCompressedOops has been used, in which case it takes 4-bytes.

I assume you are asking how to tell how much space an Object occupies. You can use Instrumentation (not a simple matter) but this will only give you a shallow depth. Java tends you break into many objects something which is C++ might be a single structure so it is not as useful.

However, ifyou have a memory issue, I suggest you a memory profiler. This will give you the shallow and deep space objects use and give you a picture across the whole system. This is often more useful as you can start with the biggest consumers and optimise those as even if you have been developing Java for ten years+ you will only be guessing where is the best place to optimise unless you have hard data.

Another way to get the object size if you don't want to use a profiler is to allocate a large array and see how much memory is consumed, You have to do this many times to get a good idea what the average size is. I would set the young space very high to avoid GCs confusing your results e.g. -XX:NewSize=1g

In Java, what is the best way to determine the size of an object?

You can use the java.lang.instrument package.

Compile and put this class in a JAR:

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);
}
}

Add the following to your MANIFEST.MF:

Premain-Class: ObjectSizeFetcher

Use the getObjectSize() method:

public class C {
private int x;
private int y;

public static void main(String [] args) {
System.out.println(ObjectSizeFetcher.getObjectSize(new C()));
}
}

Invoke with:

java -javaagent:ObjectSizeFetcherAgent.jar C

Trying to understand the footprint of ArrayList in JOLSample_16_AL_LL

ArrayList internally is backed by an Object[] as a buffer, which grows as needed.

An array of objects is actually an array of object references. In your case, it looks like each object reference is 4 bytes, so an array of them would use 4 * length bytes, plus some overhead such as the length of the array and other stuff.

When you allow the ArrayList to grow naturally, any unused indexes in the buffer array default to null, which still uses 4 bytes of memory per index.

The ArrayList that allows growth has probably expanded to (4952 - 16) / 4 = ~1234 capacity.

While the ArrayList that doesn't require growth only has 1000 capacity.

Object reference - What needs more space?

Assuming you have the Player instances somewhere else in memory already and you're going to be adding those existing objects to this list, then it comes to the same thing: Both will be lists of object references (to either a String or to a Player). Object references are small (see this answer for details, but we're talking 32 or 64 bits). The key thing here is that if you already have Player instances, adding a second reference to them is cheap; it doesn't make a copy of the object, just a copy of the reference, which is small.

Of course, if you don't already have Player instances and would be creating them just for this list, and those instances would include the name and also other information, then of course that would take more memory.

Memory requirements of an Object reference on a 64 bit JVM

In a 64-bit system, object references are typically 8-byte long. But in recent JVMs from Sun/Oracle you can enable Compressed Oops, which reduce reference size to 4 bytes at the cost of a smaller limit on heap size.



Related Topics



Leave a reply



Submit