Groovy脚本引发的 Old GC问题怎么办
发表于:2025-02-12 作者:千家信息网编辑
千家信息网最后更新 2025年02月12日,这篇文章主要为大家展示了"Groovy脚本引发的 Old GC问题怎么办",内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下"Groovy脚本引发的 Old GC
千家信息网最后更新 2025年02月12日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安全错误
数据库的锁怎样保障安全
软件开发工程师内存硬盘
服务器被登陆邮件提醒
服务器安全狗网网页版
磴口云计算网络安全工程师
应用服务器选型
宽带网络安全培训课件
数据库mysql端口号
不用服务器的计算平台
怎样把一个集合添加到数据库
大数据网络技术专业
华为云服务器基地河北
网络安全技术有鉴别机制吗
徐汇区市场软件开发厂家报价
能源行业网络安全大事
网络安全经理必读
长春正规网络技术服务诚信合作
上海软件开发中心 拟聘
数据库行长对性能影响
电子商务与网络技术是什么
我的世界服务器管理攻略
网络安全攻防技术与实战
rust双人服务器怎么看
mdb数据库对比
软件开发去无锡还是南京
数据库服务器能否部署虚拟机
成都市网络安全作业
ic卡管理系统数据库密码
球员数据库篮球
网络安全思维导图简单又漂亮
牛气科技移动互联网