Groovy脚本引发的 Old GC问题怎么办
发表于:2025-11-17 作者:千家信息网编辑
千家信息网最后更新 2025年11月17日,这篇文章主要为大家展示了"Groovy脚本引发的 Old GC问题怎么办",内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下"Groovy脚本引发的 Old GC
千家信息网最后更新 2025年11月17日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安全错误
数据库的锁怎样保障安全
有哪些是联网的软件开发
数据库脚本编程书籍
苏州苹果软件开发价钱
广州安卓软件开发市场价
温度过高服务器宕机了还能起来吗
建林社区开展网络安全教育
jsp加载数据库
百度云的云服务器
高安全等级数据库
选修3网络技术会考题库
如何删除eplan数据库
数据库中的语言类型
h3c 服务器默认管理口
互联网科技公司投资关系图
软件开发项目工作说明文档
网络安全和扫黑除恶宣传
总工会网络安全宣传总结
软件开发主修
宁波营销软件开发创新服务
网络技术国家标准
为什么会收到网络安全周提醒
潜渊症服主退了服务器会没吗
微信移动app软件开发
手机支付安全属于网络安全吗
虹口区好的软件开发推荐咨询
人才资源数据库
河北省网络安全通报预警平台
软件开发测试常见问题
服务器怎么打开端口
内蒙古计算机网络技术哪个学校好