DVK
DVK

Reputation: 129373

What is the most memory-saving data structure that can serve my purpose?

I'm trying to memory-optimize my server that keeps running into OOM.

Most of the objects (by count) in the server take the following form:

Important caveat: 95% of such hashmaps would ONLY EVER have one key; and I know whether that's the case when creating the hashmap.

There are millions of these hashmaps.

I already asked a separate question about optimizing those hashmaps memory wise, and someone in a comment suggested that perhaps re-engineering my whole data structure would be better since even with initial size of "1" HashMaps still take up extra memory.

As such, my question is; is there a better Java data structure I can implement which can store the same exact data with better memory efficiency?

NOTE: I need to be able to look up whether a specific value is present as a key; therefore I have considered but rejected storing the data in an list of quintuples of [string_value, int, boolean, boolean].

Upvotes: 2

Views: 1097

Answers (2)

Stefan Haustein
Stefan Haustein

Reputation: 18793

Expose the less specific Map interface to the user instead of HashMap, this given you the freedom to use hash maps or singleton maps depending on the case.

Memory efficient singleton maps can be created via Collections.singletonMap(): https://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#singletonMap(K,%20V)

SingletonMap seems to be implemented as an object with just two fields and some cache: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/Collections.java#Collections.SingletonMap

p.s. You could have something even more compact for your special case by collapsing the map and value into a single instance like this:

public final class SingletonAttributeMap extends Attribute implements Map<String,Attribute> {

  private final String key;

  public Attribute get(String key) {
    return this.key.equals(key) ? this : null;
  }

  ....
}

p.p.s Is there a maximum size for the integers in the attributes? You might be able to do tricks like this (whether this actually saves memory will depend on padding / alignment, see What is the memory consumption of an object in Java?):

 class Attribute {
    private int value;

    boolean getBoolean1() {
      return (value & 1) != 0; 
    }

    boolean getBoolean2() {
       return (value & 2) != 0;
    }

    int getInt() {
       return value >> 2;
    }

    void setBoolean1(boolean b) {
      value = (value & ~1) | (b ? 1 : 0);
    }

    void setInt(int i) {
      value = (value & ~3) | (i << 2);
    }

    ... 

Upvotes: 2

duffymo
duffymo

Reputation: 308743

Each object is a HashMap? Not a very good abstraction. I'd prefer composition: create an object that HAS-A HashMap and provides a clear API. Make it Comparable and implement hashCode and equals.

I would suggest that you follow the Flyweight pattern if lots of those are repeated.

If the objects are immutable and read-only this will be a perfectly good optimization.

Have a Factory object to create instances and maintain a List of unique ones. If someone asks for one that's already in the List return the immutable copy.

You can calculate how much of a memory savings this will provide before you implement it.

Upvotes: 1

Related Questions