powered by Jive Software

String.intern() problem in the internal cache

I’ve recently encountered this problem, the openfire jvm continuously did FullGCs when we ran the stress tests on it. The reason is permnent region size limit, after some digging, then we realized that the root cause lives in the design of the internal cache.

The openfire uses the DefaultLocalCacheStrategy to manage the local cache, and will getLock() to lock the cache item. Every time the getLock() was called, it will check the key’s class, and will call the String.intern() if the key is a String, which will add some string instances to the String Literal Pool in JVM. Since there are some user-related data managed in this kind of cache, the pool increases along with different users logged in. For example, if user juliet logged in, serveral strings as follows will be added to the pool:

juliet@127.0.0.1

juliet

juliet ro

juliet@127.0.0.1/coolrat

In my opinion, this designment will not only limit the user capacity because of the size of jvm permnent region, but also damage the long-run ablity since users are losing in most web sites, which will leave some garbages on the server and there is a potential permnent region exhaustion failure for the literal pool will not be garbage collected. Hence I re-designed the internal cache and removed the String.intern(), the lock was also changed because of the formal LocalLock was designed to take advantage of single-instance property of String.intern(). See more details in the attachment.

It’s also noticed that the String.intern() is ubiquitous in openfire, the patch can only relieve the XXX@127.0.0.1 like strings. Meanwhile without intern() function different users might have to synchronize when accessing same collection, and it will be slower than the former design. In this case, I’d like to use an outer maybe global lock mechanism like segments in ConcurrentHashMap to reduce access contentions, which is not in the patch now.

Please don’t get me wrong, what I disagree is use it in per-user data cache which will increase vastly and can not be controlled properly. Anyway, your mileage may vary, so would anyone like to talk something about this? Thanks in advance.