Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java object which takes the least memory

This is a silly question, but here it goes.

I have a multithreaded program and a "global" Collection of unique elements. I rejected synchronized Set implementations due to performance, for the ConcurrentHashMap. I don't really need the Value part of Map, so I wanted to use the smallest Object in java in terms of memory usage. I solved this issue in a different way (single Boolean object referenced multiple times in the Map), but I am still curious what is the smallest object in Java. I always thought it to be Boolean, but that is not true I think (Java - boolean primitive type - size, Primitive Data Types)

like image 754
alien01 Avatar asked Aug 26 '12 19:08

alien01


People also ask

How much memory does a Java object take?

an object with one long field (including a Java Date) will take up 24 bytes: 12 bytes of header, 8 bytes of data, then 4 bytes of padding to round up to an 8-byte boundary; an instance with eight boolean fields will also take up 24 bytes: 12 for the header, 8 for the booleans, plus 4 bytes of padding.

Does HashMap use more memory?

To use them inside another data structure, you have to pay the price of a pointer to the object. In Java, the best way to save memory is to use a library, like fastutil, that works directly with native types. Conclusion: Whether you use a TreeMap or HashMap seems to have very little effect on your memory usage.

How many bytes is a Java object?

Objects, References and Wrapper Classes. Minimum object size is 16 bytes for modern 64-bit JDK since the object has 12-byte header, padded to a multiple of 8 bytes.

Does object take memory?

In Java, when we only declare a variable of a class type, only a reference is created (memory is not allocated for the object). To allocate memory to an object, we must use new(). So the object is always allocated memory on the heap (See this for more details).


2 Answers

It doesn't really matter, actually, since the value part of each association is fixed to be a reference. You might even use null as value here, but any other (fixed) object reference should be fine (and more convenient sometimes). I'd prefer Boolean.TRUE (or a similar "well known" singleton). You can then test for membership via

if (myMap.get(someKey) != null) { ... }

in addition to

if (myMap.containsKey(someKey)) { ... }
like image 185
Dirk Avatar answered Sep 30 '22 19:09

Dirk


If you want a Set<K> that is backed by a ConcurrentHashMap, you should use Collections.newSetFromMap, e.g.

final Set<K> set = Collections.newSetFromMap(new ConcurrentHashMap<K, Boolean>());

Now, if you really want to reinvent the wheel, and care that much about memory usage, I suggest you merely use a plain Object as your value. Since every object in Java inherits from Object (the universal base class), the size of any object in memory must be greater than or equal to the size of a plain Object. You cannot use a primitives since generic type arguments must be Objects.

EDIT: Actually, allocating a particular object to use as your value here will take more memory than using a preexisting object which will likely be allocated for anyways. You can just use a reference to an object that will more or less always be allocated during VM initialization, e.g. Object.class. I really suggest you just use the first solution, though.

like image 39
obataku Avatar answered Sep 30 '22 17:09

obataku