Closed SimpleIto closed 7 months ago
版本:
- DynamicTp版本:1.1.6.1
问题呈现
业务在产生200多W次reject后,ThreadPoolStatProvider#stopWatchMap 已达到5164M,且无法被GC回收掉,最终干挂掉。
ThreadPoolStatProvider /** * stopWatchMap key -> Runnable value -> millis */ private final Map<Runnable, Long> stopWatchMap = new ConcurrentHashMap<>();
原因分析
本质是在“以抛异常方式”(例如juc的ThreadPoolExecutor#AbortPolicy)拒绝时,其增强代理RejectedInvocationHandler中的afterReject 则会被跳过,从而导致 ThreadPoolStatProvider#stopWatchMap 堆积只增不减。
// 此处默认true 放入stopWatch PerformanceMonitorAware @Override public void execute(Executor executor, Runnable r) { if (TRUE_STR.equals(System.getProperty(DTP_EXECUTE_ENHANCED, TRUE_STR))) { Optional.ofNullable(statProviders.get(executor)).ifPresent(p -> p.startTask(r)); // startTask() -> stopWatchMap.put(r, System.currentTimeMillis()); } } // 一系列Aware在实际execute前被调用 DtpExecutor @Override public void execute(Runnable command) { command = getEnhancedTask(command); AwareManager.execute(this, command); // here super.execute(command); } // 关键!! RejectedInvocationHandler // 会在DtpExecutor初始化时,以动态代理的方式增强我们配置的AbortPolicy @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { try { beforeReject((Runnable) args[0], (Executor) args[1]); Object result = method.invoke(target, args); // 此处抛异常,导致后续afterReject没被执行 afterReject((Runnable) args[0], (Executor) args[1]); // afterReject -> stopWatchMap.remove(r) return result; } catch (InvocationTargetException ex) { throw ex.getCause(); } }
按上述配置可轻易复现
解决
看了下调用链路,目前可通过配置
-Ddtp.execute.enhanced=false
来临时简单绕过put。但考虑到相关特性对stopWatch的使用,还是不太妥。 考虑修改RejectedInvocationHandler,将afterReject合理添至finally乐意提供PR :)
感谢,pr指派给你
版本:
问题呈现
业务在产生200多W次reject后,ThreadPoolStatProvider#stopWatchMap 已达到5164M,且无法被GC回收掉,最终干挂掉。
原因分析
本质是在“以抛异常方式”(例如juc的ThreadPoolExecutor#AbortPolicy)拒绝时,其增强代理RejectedInvocationHandler中的afterReject 则会被跳过,从而导致 ThreadPoolStatProvider#stopWatchMap 堆积只增不减。
按上述配置可轻易复现
解决
看了下调用链路,目前可通过配置
-Ddtp.execute.enhanced=false
来临时简单绕过put。但考虑到相关特性对stopWatch的使用,还是不太妥。 考虑修改RejectedInvocationHandler,将afterReject合理添至finally乐意提供PR :)