we are using Jess, which is a rules engine, written in Java. It has become pretty old and most of it is written using Java 1.5 and lower language features. Now, we are using this for many years and never noticed any problems during the Java upgrades, until now, when we plan to switch from Java 11 to Java 17.
Our runtime has become 30-40% slower, just by switching the java version. We did a lot of testing already, but cannot really find the one culprit.
For instance, we checked different Java versions and different vendors (eclipse, azul and orcacle), everything from 13+ was slower than Java 11.
Using VisualVM I was able to point down to a few methods, but there is nothing specific in there where I would say that this could be the problem.
Looking at it, it seems like there are multiple performance regressions that sum together to a big one, but that seems pretty unrealistic.
Some of the functions look like this:
private synchronized Map findVariable(String key) {
Context c = this;
while (c != null) {
Map ht = c.getVariables();
Value v = (Value) ht.get(key);
if (v != null)
return ht;
else
c = c.m_parent;
}
return null;
}
private synchronized Map getVariables() {
if (m_variables == null)
m_variables = Collections.synchronizedMap(new HashMap());
return m_variables;
}
Do you know if there are any know regressions going on from J13+, maybe regarding synchronized functions and variables for instances?
Any other pointers what might be the problem?
<=1.5
code is full of StringBuffers, Vectors, HashTables, etc – MarriageableCollections.synchronizedMap
probably produces lots of uncontested locking attempts. If re-enabling biased locking helps, then replacing those withConcurrentHashMap
s would probably help as well. (edit: oh, but "Prior to JDK 15, biased locking is always enabled"). – BenediktaValue v = (Value) ht.get(key); if (v != null) return ht;
, you can just useif(ht.containsKey(key)) return ht;
4) non-idiomatic loop. What you have here, is a classical for loop:for(Context c = this; c != null; c = c.m_parent) { Map ht = c.getVariables(); if(ht.containsKey(key)) return ht; } return null;
– Barberabarberry