JMeter 5.4.1搭配Groovy和OpenJDK16类不卸载引发OOM求解决方案
JMeter Groovy压测元空间OOM问题可行解决方案
缓存失效问题排查(核心诱因,90%以上同类问题都出自这里)
- 彻底清除脚本内的
${变量名}格式占位符:只要Groovy脚本中包含JMeter的${}语法,每次执行前JMeter都会先替换变量生成全新的脚本内容,导致你勾选的编译缓存完全失效,每次执行都会生成新的Groovy类加载到元空间。正确做法是通过JSR223默认绑定的变量读写:- 读写JMeter用户变量用
vars.get("变量名")/vars.put("变量名", 变量值) - 读写JMeter全局属性用
props.get("属性名")/props.put("属性名", 属性值)
- 读写JMeter用户变量用
- 移除脚本内动态代码执行逻辑:不要使用
evaluate()、GroovyShell等方法运行动态拼接的字符串代码,这类逻辑每次运行都会生成独立的新类,无法复用缓存。 - 不要在脚本内重复定义类/方法:如果每次执行都在脚本内定义class或者自定义方法,Groovy会为每次定义生成新类,建议将通用逻辑抽取为独立的groovy文件放到JMeter的
lib目录下全局加载,或者用@Shared注解标记公用方法/对象。
配置优化
- 你提到的移除Groovy脚本中
jmeter参数引用的方案有效:部分JMeter+Groovy版本组合中,脚本引用jmeter上下文对象会导致生成的脚本类被强关联无法被GC,改用默认绑定的ctx变量即可实现完全一致的上下文操作能力,无额外依赖。 - 调整JVM启动参数:修改jmeter.sh/jmeter.bat中的JVM配置,添加以下参数:
前者强制开启Groovy类加载器全局缓存,后者确保元空间中不再使用的类可以被正常卸载。-Dgroovy.lang.GroovyClassLoader.cacheEnabled=true -XX:+ClassUnloadingWithConcurrentMark
版本适配优化
- 优先升级Groovy小版本:JMeter 5.4.1自带的Groovy 3.0.7存在已知的类加载泄漏缺陷,不需要更换JMeter主版本,直接下载Groovy 3.0.17+稳定版,替换JMeter
lib目录下所有groovy-*.jar包即可修复泄漏问题。 - 建议JDK更换为OpenJDK 11 LTS:JDK16属于非长期支持版本,对元空间类卸载的优化不如JDK11稳定,且和部分Groovy版本的模块系统存在兼容性问题,会加剧类泄漏,压测环境优先使用LTS版本JDK可靠性更高。
内容的提问来源于stack exchange,提问作者brian muscat
相关产品推荐
相关产品推荐

