最近在项目中遇到一个内存持续增长的问题,系统启动后内存使用原本很低,但是在系统运行的过程中,内存一直在慢慢的增加,最后机器发出了内存预警,查看使用的内存,短短一个月居然达到了8G,并且jvm无法回收这些内存。
经过一系列排查,发现是大量调用groovy脚本计算导致的,使用visualVM监控jvm已加载的类数量:

发现每次调用脚本,都会增加一个类,导致堆内存一直增加,问题代码:
public static ScriptEngine engine = new ScriptEngineManager().getEngineByName("groovy");
public static Map<String,Bindings> bindingMap = new HashMap<>(1);
...
//根据当前线程得到引擎
public static Bindings getEngineBinding(){
return getEngineBinding(getCurrentThread());
}
//根据当前线程得到引擎
public static Bindings getEngineBinding(String threadNum){
return bindingMap.computeIfAbsent(threadNum, k -> engine.createBindings());
}
//根据当前线程得到引擎
public static String getCurrentThread(){
return Thread.currentThread().getName();
}
//问题代码
public stat

博客讲述了在项目中遇到的内存持续增长问题,原因是大量调用Groovy脚本导致的内存泄漏。分析发现每次执行脚本会生成并加载一个随机类,而这些类无法被有效清理。为解决此问题,作者提出了一种预编译表达式的解决方案,通过缓存编译好的脚本避免重复编译,从而减少内存占用。此外,还提供了一个封装的GroovyEngine工具类以减少并发计算时的干扰,并附带了使用示例。

7034

被折叠的 条评论
为什么被折叠?



