[java] Memory overhead of a Hashtable

Started by
6 comments, last by Blew 18 years, 7 months ago
How much memory overhead is to be expected when using a hashtable of, say, no more than 50 items? Is there any way to measure this (using J2ME on a mobile phone)?
Advertisement
Yes, you can measure it:


// create elements

int mem_before = Runtime.getRuntime().freeMemory();

// create hashtable and insert elements

int mem_after = Runtime.getRuntime().freeMemory();

int overhead = mem_before - mem_after;

// print overhead as a string on paint()
- blew
Not really accurate seeing as the GC could be freeing up memory at any time in there.
On all the phones I've been working with, garbage collecting is never done unless you call System.gc() explicitly. But yes, in theory you have a point.

A solution: call System.gc() before each call to Runtime.getRuntime().freeMemory() in the code above.
- blew
Quote:Original post by Optus
Not really accurate seeing as the GC could be freeing up memory at any time in there.


It's close enough if you are just running a test program and the Hashtable is the only object you create other than the objects it is storing.

For my own curiosity I ran three tests.

50 objects in an array uses 1176 bytes with class Object.
public class Test {    public static void main(String args[]) {        //50 Objects = 1176        System.out.println(Runtime.getRuntime().freeMemory());        Object a[] = new Object[50];        for(int i=0;i<50;i++) {            a = new Object();        }        System.out.println(Runtime.getRuntime().freeMemory());    }}


Same 50 object array with HashTable created, but not used, uses 1592 bytes. So 416 more just to create the HashTable.
public class Test {    public static void main(String args[]) {        //50 Objects + Hashtable = 1592        System.out.println(Runtime.getRuntime().freeMemory());        Object a[] = new Object[50];        Hashtable h = new Hashtable();        for(int i=0;i<50;i++) {            a = new Object();        }        System.out.println(Runtime.getRuntime().freeMemory());    }}


Same array with each element stored in the HashTable and the element acts as its own key. Uses 3488 bytes. 1896 more bytes for the storage.
public class Test {    public static void main(String args[]) {        //50 Objects = 1176        //50 Objects + Hashtable = 1592        //50 Objects + Hashtable + 50 Keys = 3488        System.out.println(Runtime.getRuntime().freeMemory());        Object a[] = new Object[50];        Hashtable h = new Hashtable();        for(int i=0;i<50;i++) {            a = new Object();            h.put(a, a);        }        System.out.println(Runtime.getRuntime().freeMemory());    }}


Also don't forget that this is run on a J2SE platform. It might use less overhead on J2ME.
"None of us learn in a vacuum; we all stand on the shoulders of giants such as Wirth and Knuth and thousands of others. Lend your shoulders to building the future!" - Michael Abrash[JavaGaming.org][The Java Tutorial][Slick][LWJGL][LWJGL Tutorials for NeHe][LWJGL Wiki][jMonkey Engine]
Heh, nice one CaptainJester.
- blew
Thank you very much, CaptainJester - your effort is very appreciated :)

I ran some tests myself. System.gc() was called before the test.

On the SonyEricsson JP3 platform, The default Hashtable alone eats some 440 bytes, with an intial capacity of a hundred, I think it was only marginally more. What eats more memory are the 16-byte-structs to store the info in. (I suppose it's: hash code, high load linked list/array reference, key reference and value reference).

I stored 100 unique strings in a hashtable of capacity 100 (not really sure whether that's 100 TOTAL capacity or 100 'optimal' capacity).

The Hashtable had an overhead of about 3.5k, which is fairly negligible - it's the size of a 40x40 picture in memory.

This means that I can probably use two or three hashtables throughout my program, one to manage a dozen images with fully qualified file names, one to manage two or three dozen internationalized strings, and one to manage a hand full of sounds with file names.
Really, hashtables are no problem - nor other data structures. The resources they hold are the big issue. Images and sounds eat up your memory very fast. Make sure you only have them in memory when needed.

Also, an Image object is much larger than a byte array with the contents of that image's file. You can keep your images' byte arrays in a hashtable and only create the Image objects when you're about to render them. When you're no longer rendering those Image objects just throw them away and garbage collect.

If memory is really a problem this technique is quite good. I use it on my Series 40 projects.
- blew

This topic is closed to new replies.

Advertisement