动态生成大量不同的aviator表达式导致metaSpace OOM,FGC无法正确回收
Tofreedom7 opened this issue · 7 comments
java8 + 5.4.1+开启了cached
示例代码(模拟了下业务场景):
public String testOOM() { log.info("testOOM"); Map<String, Object> map = Maps.newHashMap(); Random random = new Random(); long abc = random.nextLong()%10000000L; map.put("abc", new BigDecimal(abc)); try { while (true) { long cde = random.nextLong()%10000000L; String expression = "abc + " + cde; com.googlecode.aviator.Expression compiledExp = AviatorEvaluator.compile(expression, true); BigDecimal res = ((BigDecimal) compiledExp.execute(map)).setScale(0, RoundingMode.HALF_UP); log.info("res: {}, abc: {}, cde: {}, expression: {}", res, abc, cde, expression); } } catch (Exception e) { log.error("testOOM", e); return "fail|"+e.getMessage(); } }
代码原理是在死循环内 生成 abc + 随机数 的aviator的表达式,然后丢给aviator引擎做编译
大量生产aviator表达式造成metaSpaceOOM:
求各位大佬帮帮看看原因
你都完全随机了,还 cache 啥呢? cache 住就全部 class 都没办法被回收了。
你都完全随机了,还 cache 啥呢? cache 住就全部 class 都没办法被回收了。
@killme2008 大佬,业务场景也有需要固定的表达式需要做缓存,这种场景下怎么处理合适呢?
@killme2008 再请教下,为什么cache住就不会被GC回收了呢
那就固定的才 cache,不固定的就别去 cache,或者每次重新编译就调用下 invalidateCache 主动失效缓存
最佳实践都有介绍 https://www.yuque.com/boyan-avfmj/aviatorscript/ou23gy#PMc8K
@killme2008 再请教下,为什么cache住就不会被GC回收了呢
这个问题你应该去复习下 java gc 的机制。如果从 root 出发有 reference,怎么能回收呢? instance -> class
可以仔细看下最佳实践的缓存管理和匿名类卸载这块。
我先关闭了。
@killme2008 再请教下,为什么cache住就不会被GC回收了呢
这个问题你应该去复习下 java gc 的机制。如果从 root 出发有 reference,怎么能回收呢? instance -> class
@killme2008 缓存不会自动清理吗?