Daniel Pereira
Daniel Pereira

Reputation: 2785

How can I optimize the code to always use the same reference to a String without increasing the memory usage?

I am working on an application that has a lot of duplicate Strings and my task is to eliminate them to decrease memory usage. My first thought was to use String.intern to guarantee that only one reference of a String would exist. It worked to decrease the heap memory, but it increased the PermGen way too much; in fact, because there are many strings that are declared only once, the total amount of memory used by the application increased, actually.

After searching for another ideas, I found this approach: https://stackoverflow.com/a/725822/1384913.

It happened the same thing as String.intern: The String usage decreased, but the memory that I saved is being used in the WeakHashMap and WeakHashMap$Entry classes.

Is there an effective way to maintain only one reference for each String that doesn't spend the same amount of memory that I'm recovering doing it?

Upvotes: 9

Views: 445

Answers (3)

Daniel Pereira
Daniel Pereira

Reputation: 2785

I found an alternative to WeakHashMap: the WeakHashSet provided by Eclipse JDT library. It has the same behaviour that WeakHashMap, but it uses less memory. Also, you only need to call the method add and it will add the String in the set if it doesn't exist yet, or returning the existing one otherwise.

The only thing that I didn't like was the fact that it doesn't use generics, forcing the developer to cast the objects. My intern method turned out to be pretty simple, as you can see bellow:

Declaration of the WeakHashSet:

private static WeakHashSet stringPool = new WeakHashSet(30000); //30 thousand is the average number of Strings that the application keeps.

and the intern method:

public static String intern(String value) {
    if(value == null) {
        return null;
    }
    return (String) stringPool.add(value);
}

Upvotes: 1

ppeterka
ppeterka

Reputation: 20726

In a similar case, wherever possible, I refactored the string constants to enums. That way, you get two benefits:

  • enum instances are singletons, so you won't have memory problems
  • no typos when using Strings.

Cons:

  • a lot of work, with endless possibilities to make mistakes, if you don't have enough test cases
  • sometimes this is not trivial, for example when you have to interact with third party libraries you can't just edit...
  • simply a no-go if these are runtime determined, and not compile time...

Upvotes: 0

Ankur Shanbhag
Ankur Shanbhag

Reputation: 7804

Why dont you use StringBuilder/StringBuffer class instead of String. Using instance of this class, you can always use same instance with different values. - Ankur

Upvotes: 0

Related Questions