threadlocal內存泄露原因和使用方式

原因

  • 泄漏原因:
    • 存在引用Thread->ThreadLocal.ThreadLocalMap->Entry->value。
    • 線程池場景下Thread回收複用,value永遠無法被gc。參考
    static class ThreadLocalMap {
        static class Entry extends WeakReference<ThreadLocal<?>> {
            /** The value associated with this ThreadLocal. */
            Object value;

            Entry(ThreadLocal<?> k, Object v) {
                super(k);
                value = v;
            }
        }

使用方式

  • 結合方法註解作爲線程緩存,校驗、上下文傳參。
  • Threadlocal相關的操作最好放在同一個類中,最後使用remove清除ThreadLocalMap對Entry的引用。
  • 校驗方法可以傳出入參給下一步使用。
    @Around("@annotation(validateEdit)")
    public Object validateEdit(ProceedingJoinPoint joinPoint, ValidateEdit validateEdit) throws Throwable {
        try {
            MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
            String methodName = methodSignature.getMethod().getName();
            Class<?>[] parameterTypes = methodSignature.getMethod().getParameterTypes();
            Annotation[][] annotations = joinPoint.getTarget().getClass().getMethod(methodName, parameterTypes).getParameterAnnotations();
            Object[] args = joinPoint.getArgs();

            for (int i = 0; i < args.length; ++i) {
                for (Annotation annotation : annotations[i]) {
                    //校驗、設置上下文
                }
            }

            return joinPoint.proceed();
        } finally {
            ThreadCacheHolder.remove();
        }
    }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章