In a threaded environment, the synchronization here can potentially become a bottleneck.
There is no easy solution for that if you stick to JDK classes, since they do not provide a con-
current hashmap for weak references. However, there have been proposals to add a Cus-
tomConcurrentHashMap to the JDK (originally as part of Java Specification Request, or
JSR, 166), and you can find various third-party implementations of such a class.
1. Objects that are immutable offer the possibility of special lifecycle management:
2. Eliminating duplicate copies of immutable objects via canonicalization can
greatly decrease the amount of heap an application uses.
Strings are, far and away, the most common Java object; your application's heap is almost
certainly filled with them.
If a large number of those strings are the same, then a large part of the heap is wasted. Since
strings are immutable, there is never any reason to have more than one string representing
the same sequence of characters. Programming being what it is, though, it can be hard to
know if you are creating duplicate strings.
Knowing if you have a large number of duplicate strings requires some heap analysis. One
way to do that is to load a heap dump in the Eclipse Memory Analyzer, calculate the retained
size for all the String objects, and list those objects sorted by their maximum retained size.
Figure 7-6 shows such a heap dump. It seems likely that the first three strings are the same,
and that interning them would save 650 KB of memory. (The strings can be inspected in the
tool for verification.) The same is true of the fourth and fifth strings, the seventh though
ninth strings, and so on—except of course the lower in the list, the less memory that is saved
by interning the string.
This is a case where interning those particular strings is advantageous; retaining only the ca-
nonical version of the string can save all the memory allocated by those duplicate cases. That
could be done with a variant of the canonicalization example in the previous section, but the
String class provides its own method to perform canonicalization: the intern() method.