使用mybatis拼接sql导致的问题,可能是in条件过多。
今天生产遇到报错,可惜日志没有全部复制下来就被同事给重启了,容器中的日志全部没了。
报错内容大概如下:
nested exception is org.apache.ibatis.builder.BuilderException:
Error evaluating expression 'ew.sqlSegment != null and ew.sqlSegment != '' and ew.nonEmptyOfWhere'.
Cause: org.apache.ibatis.ognl.OgnlException:
sqlSegment [java.lang.OutOfMemoryError: GC overhead limit exceeded
乍一看,是oom,但具体又是GC的问题。
导致这种情况是因为:频繁的进行内存回收(最起码已经进行了5次连续的垃圾回收),JVM就会曝出java.lang.OutOfMemoryError: GC overhead limit exceeded错误。(oracle官方解释)
出现这种情况,看别人有的是没有分页,查询出来的数据太多,导致内存超出了限制。
我这里是mybatis报错,报的是builder,加上expression,还有ognl,这几个词,推测是条件拼接太多,导致报错。
例如,有的直接拼了几千个上万个id。
oracle官方解释如下:
Exception in thread thread_name:
java.lang.OutOfMemoryError: GC Overhead limit exceeded Cause:
The detail message "GC overhead limit exceeded" indicates that
the garbage collector is running all the time
and Java program is making very slow progress.
After a garbage collection,
if the Java process is spending more than approximately 98% of its time doing garbage collection
and if it is recovering less than 2% of the heap
and has been doing so far the last 5 (compile time constant) consecutive garbage collections,
then a java.lang.OutOfMemoryError is thrown.
This exception is typically thrown
because the amount of live data barely fits into the Java heap having little free space for new allocations.
Action: Increase the heap size.
The java.lang.OutOfMemoryError exception for GC Overhead limit exceeded can be turned off with the command line flag -XX:-UseGCOverheadLimit.
官方建议是:增加堆大小,启动脚本添加参数-Xmx1024m。
或者 关闭GC Overhead limit:-XX:-UseGCOverheadLimit
但这些都不建议。因为根本不是这里出的问题,而是代码的问题。改这些又有可能会引发其他问题如java.lang.OutOfMemoryError: Java heap space错误
线上频繁fullgc、oldgc,MybatisPlus踩坑_old gc频繁_BruceChao5211的博客-CSDN博客
GC overhead limit exceeded原因分析及解决方案 - 知乎
OutOfMemoryError: GC Overhead Limit Exceeded错误处理_rainyonelove的博客-CSDN博客
=======================分割线==========================
文章到此已经结束,以下是紫薯布丁
nested exception is org.apache.ibatis.builder.BuilderException:
Error evaluating expression 'ew.sqlSegment != null and ew.sqlSegment != '' and ew.nonEmptyOfWhere'.
Cause: org.apache.ibatis.ognl.OgnlException:
sqlSegment [java.lang.OutOfMemoryError: GC overhead limit exceeded
Exception in thread thread_name:
java.lang.OutOfMemoryError: GC Overhead limit exceeded Cause:
The detail message "GC overhead limit exceeded" indicates that
the garbage collector is running all the time
and Java program is making very slow progress.
After a garbage collection,
if the Java process is spending more than approximately 98% of its time doing garbage collection
and if it is recovering less than 2% of the heap
and has been doing so far the last 5 (compile time constant) consecutive garbage collections,
then a java.lang.OutOfMemoryError is thrown.
This exception is typically thrown
because the amount of live data barely fits into the Java heap having little free space for new allocations.
Action: Increase the heap size.
The java.lang.OutOfMemoryError exception for GC Overhead limit exceeded can be turned off with the command line flag -XX:-UseGCOverheadLimit.