Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java largest object size in Heap

Tags:

java

If I set the maximum Java heap size -Xmx512m, when what is the possible maximum size for an single object?

Suppose, my application has only a single class and I'm creating exactly a single object.

Is there any approximate size limit for that object?

My class looks something like the one below:

public class BigSingleObj {
    //conf will contain thousand of String.
    private Map<String, String> conf = new HashMap<String, String>();
    public String getConf(String key) {
        return conf.get(key);
    }
}

NOTE

As I mentioned my JVM heap size, I'm requesting to answer something quantitative.

like image 422
mmuzahid Avatar asked Feb 08 '23 10:02

mmuzahid


2 Answers

It depends on JRE which you are using. Whether you are using x64 - then more space your object will take.

You can use JOL (Java Object Layout) to calculate how large will be your object.

This will give you an idea how much space it takes.

like image 198
Igor Konoplyanko Avatar answered Feb 10 '23 01:02

Igor Konoplyanko


The theoretical1 largest single Java object you will be able to create (if you have a large enough heap) will be a long[] with 231 - 1 elements. That is 16GB. In theory.

But the largest object you are going to be able to create for a given heap size is platform dependent.

  1. In practice the maximum array length is JVM specific and is slightly less than 231 - 1; see Do Java arrays have a maximum size?

  2. The JVM's heap is segmented into two or more "spaces", and any given object must fit inside a single space1. An object that approaches the size of the entire heap is impossible because of this, and because various other heap-related overheads.

The default sizes of the various GC spaces are calculated by the memory manager, and I've never come across a simple formula that predicts what the sizes will be.

So, if you really want to know the largest object you can allocate, then your best bet is to measure it experimentally. Write a simple program that allocates successively larger arrays until you get an OOME. But note that the answer you get will depend on your VM version and on the JVM command line options you use.


Suppose, my application has only a single class and I'm creating exactly a single object.

Your BigSingleObj class is not actually allocating a large object at all. The HashMap will start out small2, and will automatically grow as entries are added to it.

Furthermore, the HashMap object is actually composed of a number of objects. The largest of these will be the hash array, but the total size of the HashMap will be 5 or more times the size of that array. And then you need to add the space occupied by the keys and values ... which in your case will depend on the string sizes.

All of this means that the size of largest allocatable object in Java is not a useful predictor of how many entries you can store in your big HashMap.


As this answer notes, you can use the JOL tool to determine the size of an instance of a given Java type. However, it relies on measuring the size of an instance (in various ways) rather than predicting what it would be. In your example, it would give a misleading answer (see footnote 2) unless you populated the map before measuring it.


1 - It is more complicated with G1GC. It splits the old generation into many standard-sized regions that can be collected independently. If an object is more than half the size of a standard region, G1GC classes it as "humongous", and creates a "humongous region" to hold it. This may trigger a full collection to (in effect) defragment at the region level. Even so, the process of creating a humongous region may fail if the heap is already too close to full or too fragmented.
2 - Even if you supply a large capacity argument, current versions of HashMap will defer the allocation of the internal hash array until it is needed.

like image 28
Stephen C Avatar answered Feb 10 '23 02:02

Stephen C