Sign in to follow this  
Thygrrr

[java] Memory overhead of a Hashtable

Recommended Posts

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)?

Share this post


Link to post
Share on other sites
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()

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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[i] = 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[i] = 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[i] = new Object();
h.put(a[i], a[i]);
}
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this