Off-heap Hash Map in Java, part 2

I spent some time trying to re-produce issue we had in production which justified usage of Off-heap hash map. And it was a total fail! In theory I knew that it is related to cases when app needs huge maps consuming almost all heap memory and those maps are not static, they are constantly changed triggering Full GC cycles. Anyway I got some interesting results just comparing time and memory usage of map population.

So I had this simple code to create a map. OHM uses same interface as HashMap so it is pretty simply to test them both.

public class HashMapTest {
    public static void main(String[] args) {
        //final Map<String, String> map = new HashMap<>(15_000_000, 0.9f);
        final Map<String, String> map = new OHMap<>(15_000_000);
 
        for (int i = 0; i < 10; i++) {
            map.clear();
 
            System.out.print("Loading map...");
            long start = System.currentTimeMillis();
            populateMap(map);
            long end = System.currentTimeMillis();
            System.out.println("Done in " + (end - start) + "ms.");
        }
    }
 
    private static void populateMap(Map<String, String> map) {
        for (int i = 0; i < 10 * 1000_000; i++) {
            map.put(String.valueOf(i), UUID.randomUUID().toString());
        }
    }
}

I started with OpenJDK 8 and as expected OHM was slower than HashMap: 33ms vs 23ms. But memory consumption is quit opposite! I had to pump -Xmx to 3Gb to make HashMap test work and total memory used by Java process was 3181Mb. OHM worked even with -Xmx1G though total memory consumption was also close to 3Gb.

Now the most interesting results (prompted me to post this) I got from using OpenJDK 11! The performance difference between HashMap and OHM was shocking: 17ms vs. 34ms!!! And memory consumption for HasMap test with -Xmx3G was lower than 3Gb!

Undoubtedly Java engineers did a good job with core JDK11. With such results I may no need of OHM in production when we switch to Java 11. But I still wasn’t able to re-produce the state of continuous GC cycles with huge hash maps. My next try will be adding multi-threading to get closer to production use case.

Leave a Reply

Your email address will not be published. Required fields are marked *