Search before asking
AREX Test Service
AREX Java Agent (arextest/arex-agent-java)
Current Behavior
WeakReferenceKey + ArexThreadLocal.Transmitter.Snapshot + HashMap 对象增加,内存持续上涨
Expected Behavior
我希望了解:为何 ForkJoinTask 插桩设计为依赖弱引用 + WeakCache.check() 做驱逐,而不是在任务执行结束时显式 remove?** 在我们的环境中,该设计会导致缓存无界增长。
当前设计
1. ForkJoinTask 构造时 put
ForkJoinTaskConstructorInstrumentation 捕获上下文并写入静态缓存:
// ForkJoinTaskConstructorInstrumentation.ConstructorAdvice
final Object captured = ArexThreadLocal.Transmitter.capture();
if (captured != null) {
Cache.CAPTURED_CACHE.put(task, captured);
}
2. exec/run 时 get + replay
// ForkJoinTaskInstrumentation.ExecAdvice.onEnter
final Object captured = Cache.CAPTURED_CACHE.get(task);
backup = ArexThreadLocal.Transmitter.replay(captured);
3. 退出时仅 restore,无 remove
// ForkJoinTaskInstrumentation.ExecAdvice.onExit
ArexThreadLocal.Transmitter.restore(backup);
// 缺少:Cache.CAPTURED_CACHE.remove(task);
4. 驱逐依赖 WeakCache.check() + GC
// WeakCache:Key 为 WeakReference<ForkJoinTask>,Value(Snapshot)为强引用
void check() {
while ((reference = poll()) != null) {
target.remove(reference); // 仅当 ForkJoinTask 被 GC 并入队后
}
}
### Steps To Reproduce
JDK 21 / 虚拟线程背景
我们的复现环境(Spring Boot + JDK 21):
@GetMapping("/test1")
public String hello() {
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
for (int i = 1; i <= 10; i++) {
executor.submit(() -> log.info("hello: {}", n));
}
}
return "success";
}
### Anything else
_No response_
### Are you willing to submit a pull request to fix on your own?
- [ ] Yes I am willing to submit a pull request on my own!
Search before asking
AREX Test Service
AREX Java Agent (arextest/arex-agent-java)
Current Behavior
WeakReferenceKey + ArexThreadLocal.Transmitter.Snapshot + HashMap 对象增加,内存持续上涨
Expected Behavior
我希望了解:为何 ForkJoinTask 插桩设计为依赖弱引用 +
WeakCache.check()做驱逐,而不是在任务执行结束时显式 remove?** 在我们的环境中,该设计会导致缓存无界增长。当前设计
1. ForkJoinTask 构造时 put
ForkJoinTaskConstructorInstrumentation捕获上下文并写入静态缓存: