Use PermGen space or native start method?

I am writing Codec to process messages sent over TCP using a protocol based protocol. During the decoding process, I create several String s, BigDecimal and dates. Client-server access patterns mean that the client usually issues a request and then decodes thousands of response messages, resulting in a lot of duplicate String s, BigDecimal s, etc.

So I created an InternPool<T> class that allows me to put every class of an object. Internally, the pool uses WeakHashMap<T, WeakReference<T>> . For example:

 InternPool<BigDecimal> pool = new InternPool<BigDecimal>(); ... // Read BigDecimal from in buffer and then intern. BigDecimal quantity = pool.intern(readBigDecimal(in)); 

My question is: I use InternPool for BigDecimal , but should I use it for the String method instead of String intern() , which I believe uses PermGen space? What is the advantage of using PermGen space?

+7
java garbage-collection permgen string-interning
source share
2 answers

It is possible that the JVM String.intern() pool will be faster. AFAIK, it is implemented in native code, so theoretically it should be faster and use less space than the pool implemented using WeakHashMap and WeakReference . To confirm this, you need to do a thorough benchmarking.

However, if you do not have a large number of long-lived duplicate objects, I doubt that interning (either in permGen or in your own pools) will be of great importance. And if the ratio of unique to duplicate objects is too low, interning will simply increase the number of living objects (which will make the GC longer) and decrease productivity due to overhead costs for interning, etc. Therefore, I also advocate a comparative analysis of the intern and no approach.

+2
source share

If you already have an InternPool class, it thinks it's better to use it than choose a different interning method for strings. Especially since String.intern() seems to give a much stronger guarantee than you actually are. Your goal is to reduce memory usage, so the perfect internment for a lifetime JVM is not really required.

In addition, I would use the Google MapMaker Collections to create InternPool to avoid re-creating the wheel:

 Map<BigDecimal,BigDecimal> bigDecimalPool = new MapMaker() .weakKeys() .weakValues() .expiration(1, TimeUnits.MINUTES) .makeComputingMap( new Function<BigDecimal, BigDecimal>() { public BigDecimal apply(BigDecimal value) { return value; } }); 

This will give you (correctly implemented) weak keys and values, thread safety, automatic cleaning of old records and a very simple interface (simple, well-known Map ). To be sure, you could also wrap it using Collections.immutableMap() to avoid code misuse.

+4
source share

All Articles