jess 在从 java 11 升级至 java 13 及更高版本后出现 30–40% 的运行时性能下降,主因是 jdk 默认禁用偏向锁(biased locking),而该引擎大量依赖 `synchronized` 方法(如 `findvariable()` 和 `getvariables()`),其性能在无偏向锁时急剧劣化。
Jess 是一款基于 Java 1.5 时代设计的老牌规则引擎,其核心同步逻辑广泛使用 synchronized 实例方法(如示例中 findVariable() 和 getVariables())。这类轻量级、高频率调用的同步块,在 Java 11 及之前默认启用偏向锁(Biased Locking) 时表现极佳:JVM 会将锁“绑定”到首次获得它的线程,避免多数场景下的 CAS 开销和 Monitor 进入/退出成本。
然而,自 Java 15 起,偏向锁被彻底移除;Java 13–14 已默认禁用(通过 JEP 374),且主流厂商(Oracle、Eclipse Temurin、Azul Zulu)均遵循此行为。这意味着所有 synchronized 块(包括无竞争的单线程调用路径)都将退化为更重的轻量级锁 → 重量级锁路径,引发显著的内存屏障、OS 线程调度及 Monitor 对象分配开销——而这正是你通过 VisualVM 观察到的“多处微小退化叠加成大幅下降”的本质:不是某一行代码变慢,而是每个 synchronized 调用的底层锁机制成本翻倍。
✅ 验证与临时修复方案(推荐用于生产过渡):
在启动 Jess 应用时,显式启用偏向锁(仅适用于 Java 13–14;Java 15+ 不支持):
java -XX:+UseBiasedLocking -XX:BiasedLockingStartupDelay=0 \
-jar your-jess-app.jar
⚠️ 注意:-XX:BiasedLockingStartupDelay=0 强制 JVM 启动即启用偏向锁(默认延迟 4 秒),避免初始化阶段误判为“无竞争”而跳过偏向。
❌ 不推荐的替代方案:
- 升级到 Java 17 并尝试 -XX:+UseBiasedLocking?无效——该参数在 Java 17 中已被完全移除,JVM 将静默忽略并打印警告。
- 替换 Collections.synchronizedMap(new HashMap()) 为 ConcurrentHashMap?虽可消除部分同步开销,但需深度修改 Jess 内部状态模型(如 Context 链式作用域、变量可见性语义),风险极高,且无法解决 findVariable() 中的 synchronized 方法调用瓶颈。
? 长期建议: