Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Java, empty HashMap space allocation

How can i tell how much space a pre-sized HashMap takes up before any elements are added? For example how do i determine how much memory the following takes up?

HashMap<String, Object> map = new HashMap<String, Object>(1000000);
like image 489
richs Avatar asked Dec 28 '22 00:12

richs


2 Answers

In principle, you can:

  • calculate it by theory:
    • look at the implementation of HashMap to figure out what this method does.
    • look at the implementation of the VM to know how much space the individual created objects take.
  • measure it somehow.

Most of the other answers are about the second way, so I'll look at the first one (in OpenJDK source, 1.6.0_20).

The constructor uses a capacity that is the next power of two >= your initialCapacity parameter, thus 1048576 = 2^20 in our case. It then creates an new Entry[capacity] and assigns it to the table variable. (Additionally it assigns some primitive variables).

So, we now have one quite small HashMap object (it contains only 3 ints, one float and one reference variable), and one quite big Entry[] object. This array needs space for their array elements (which are normal reference variables) and some metadata (size, class).

So, it comes down to how big a reference variable is. This depends on VM implementation - usually in 32-bit VMs it is 32 bit (= 4 bytes), in 64-bit VMs 64 bit (= 8 bytes).

So, basically on 32-bit VMs your array takes 4 MB, on 64-bit VMs it takes 8 MB, plus some tiny administration data.


If you then fill your HashTable with mappings, each mapping corresponds to a Entry object. This entry object consists of one int and three references, taking about 24 bytes on 32-bit VMs, maybe the double on 64-bit VMs. Thus your 1000000-mappings HashMap (assuming an load factor > 1) would take ~28 MB on 32-bit-VMs and ~56 MB on 64-bit VMs.

Additionally to the key and value objects themselves, of course.

like image 137
Paŭlo Ebermann Avatar answered Dec 30 '22 15:12

Paŭlo Ebermann


You could check memory usage before and after creation of the variable. For example:

long preMemUsage = Runtime.getRuntime().totalMemory() -
      Runtime.getRuntime().freeMemory();
HashMap<String> map = new HashMap<String>(1000000);
long postMemUsage = Runtime.getRuntime().totalMemory() -
      Runtime.getRuntime().freeMemory();
like image 45
dmcnelis Avatar answered Dec 30 '22 13:12

dmcnelis