Groovy脚本引发的 Old GC问题怎么办
发表于:2026-11-04 作者:千家信息网编辑
千家信息网最后更新 2026年11月04日,这篇文章主要为大家展示了"Groovy脚本引发的 Old GC问题怎么办",内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下"Groovy脚本引发的 Old GC
千家信息网最后更新 2026年11月04日Groovy脚本引发的 Old GC问题怎么办
这篇文章主要为大家展示了"Groovy脚本引发的 Old GC问题怎么办",内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下"Groovy脚本引发的 Old GC问题怎么办"这篇文章吧。
示例代码如下
ScriptEngineManager factory = new ScriptEngineManager();ScriptEngine engine = factory.getEngineByName("groovy");String function = String.format("def getTargetParamValue(%s) {return \"%s\"}", "o", "$o");engine.eval(function);Invocable invocable = (Invocable) engine;Object result = invocable.invokeFunction("getTargetParamValue", "test-string");System.out.println(result);这段代码定义了一个Groovy的方法,根据传进去的参数返回对应的值。
由于生产环境流量很大,这段代码被频繁执行。测试时的代码如下
public class ScriptEngineTest { public static void main(String[] args) { ScriptEngineManager factory = new ScriptEngineManager(); ScriptEngine engine = factory.getEngineByName("groovy"); //测试时改为死循环 for (int i = 0;; i++) { try { String function = String.format("def getTargetParamValue(%s) {return \"%s\"}", "o", "$o"); engine.eval(function); Invocable invocable = (Invocable) engine; Object result = invocable.invokeFunction("getTargetParamValue", "test-string"); System.out.println(result); TimeUnit.MICROSECONDS.sleep(100); System.out.println(new Date().toLocaleString()); } catch (Exception e) { String errorMsg = String.format("异常!%s", e.getMessage()); System.out.println(errorMsg); } } }}模拟生产环境的情况,每秒钟执行10次。通过VusualVM观察JVM
CPU使用情况,可以看到在每次堆内存扩容的时候,CPU使用量会有明显增加
堆内存使用情况
metaspace使用量一直在增加
类加载情况,total loaded classes一直在增加
线程
dump内存
可见,每次循环中生成的 Groovy method在方法执行完成之后并没有被释放掉,导致metaspace的使用量一直增加,最终撑爆JVM
针对以上问题,解决方法为每次将生成的方法缓存下了,下次要执行的时候从缓存中取。
private final ConcurrentHashMapconcurrentHashMap = new ConcurrentHashMap<>();private Object getInvokeResult(Object targetParam, String paramName, String expression) throws Exception { //targetParamClassName="com.umgsai.web.home.vo.NodeVO" String targetParamClassName = targetParam.getClass().getName(); //expression="$nodeVO.bizOwner" //paramName="nodeVO" String functionKey = String.format("%s_%s_%s", targetParamClassName, paramName, expression); functionKey = StringUtil.replaceChars(functionKey, "$", ""); functionKey = StringUtil.replaceChars(functionKey, ".", "_"); //functionKey为方法的名称和concurrentHashMap的key,这里需要去掉特殊字符 Invocable invocable = concurrentHashMap.get(functionKey); if (invocable != null) { //如果缓存中有,直接调用 return invocable.invokeFunction(functionKey, targetParam); } //如果缓存中没有,生成方法,并且存到concurrentHashMap synchronized (lock) { invocable = concurrentHashMap.get(functionKey); if (invocable == null) { String function = String.format("def %s(%s) {return \"%s\"}", functionKey, paramName, expression); engine.eval(function); invocable = (Invocable) engine; concurrentHashMap.put(functionKey, invocable); if (log.isInfoEnabled()) { String msg = String.format("Create new Groovy function, functionKey=%s, paramName=%s, expression=%s", functionKey, paramName, expression); log.info(msg); } } } if (log.isInfoEnabled()) { log.info(String.format("Groovy function concurrentHashMap.size=%d", concurrentHashMap.size())); } return invocable.invokeFunction(functionKey, targetParam);}
以上是"Groovy脚本引发的 Old GC问题怎么办"这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!
方法
问题
代码
情况
缓存
怎么办
脚本
使用量
内存
内容
篇文章
生成
时候
环境
学习
帮助
循环
测试
生产
很大
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
互联网新科技
科技股互联网
厦门中拓互联网络科技有限公司
奇酷互联网络科技公司
米客互联网科技
互联网高科技企业
科技互联网创业计划书
西藏七维空间互联网科技有限公司
来此购互联网科技有限公司
互联网科技公司实习生
和信科技工业互联网
宁波跨境商互联网科技有限公司
互联网硬科技公司
昆明中奇联合互联网科技
云鲸互联网络科技有限公司
互联网时代科技型公司的机会
互联网领先科技活动
易租星互联网科技有限公司
玉溪新华互联网科技怎么选
互联网科技大佬云集
互联网络科技
鸠鸠互联网科技
广州互联网科技公司
睿民互联网科技
互联网科技宣传片
美国互联网前沿科技
青岛中康互联网医疗科技有限公司
广州富喜互联网络科技
福仕德教育科技互联网
互联网科技对化妆品行业