Why Netty’s IntObjectHashMap Beats HashMap: Deep Dive into Performance and Design

This article explores Netty’s IntObjectHashMap, explaining how its use of primitive int keys and open‑addressing linear probing reduces memory overhead and improves performance compared to standard HashMap, while detailing its source‑code evolution, capacity handling, probing strategy, load factor, and deletion compaction.

Java Backend Technology
Java Backend Technology
Java Backend Technology
Why Netty’s IntObjectHashMap Beats HashMap: Deep Dive into Performance and Design

Background

In a Bilibili video about high‑concurrency ticket pricing, Qunar’s engineers showed that compressing data saved 204C and 2160C of server resources, equivalent to 591 machines.

One of the techniques they used was replacing the standard HashMap with Netty’s IntObjectHashMap, which stores primitive int keys.

Finding the Source

The author fetched the Netty source, discovered that IntObjectHashMap is not present in the 4.1 branch but exists in 4.0. The class and its benchmark test were located and examined.

Key Design Points

Uses open addressing with linear probing to resolve hash collisions, minimizing memory footprint.

Key type is primitive int, avoiding the overhead of boxed Integer objects.

Value is stored directly as an Object without extra node structures.

hashIndex Evolution

The method that maps an int key to an index evolved through three commits:

return (key % keys.length + keys.length) % keys.length;

This formula guarantees a non‑negative index regardless of the sign of the key.

put Method Walkthrough

The put method first obtains the index via hashIndex, then checks value[index] == null. If the slot is empty, the key and value are stored; otherwise the method probes the next slot (wrapping to 0 at the end) until an empty slot or the original start index is reached, at which point an “Unable to insert” exception is thrown.

Capacity and Load Factor

The constructor adjusts the requested capacity to an odd number because even capacities can break probing (in 4.0). The maxSize is computed as capacity * loadFactor, with a default load factor of 0.5. A smaller load factor triggers earlier resizing, while a larger one delays it.

Deletion and Compaction

When an entry is removed, the map performs a compaction step that may shift subsequent entries to fill the gap, potentially costing O(N) in the worst case. This is why a modest load factor is recommended.

Later Changes

GitHub issue #2659 shows that the map originally used double hashing and was later switched to linear probing, along with other optimizations such as a different capacity‑adjustment strategy in Netty 4.1.

Conclusion

IntObjectHashMap achieves better performance than HashMap by eliminating boxed keys, reducing per‑entry overhead, and using a memory‑efficient probing strategy, making it suitable for high‑throughput scenarios like Qunar’s ticket‑pricing service.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaNettyHashMapData StructuresIntObjectHashMap
Java Backend Technology
Written by

Java Backend Technology

Focus on Java-related technologies: SSM, Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading. Occasionally cover DevOps tools like Jenkins, Nexus, Docker, and ELK. Also share technical insights from time to time, committed to Java full-stack development!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.