解决方案
ThreadLocal 内存溢出的解决方案很简单,我们只需要在使用完 ThreadLocal 之后,执行 remove 方法就可以避免内存溢出问题的发生了,比如以下代码:
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
publicclass App {
/**
* 定义一个 10m 大的类
*/
staticclass MyTask {
// 创建一个 10m 的数组(单位转换是 1M -> 1024KB -> 1024*1024B)
privatebyte[] bytes = newbyte[10 * 1024 * 1024];
}
// 定义 ThreadLocal
privatestatic ThreadLocal<MyTask> taskThreadLocal = new ThreadLocal<>();
// 测试代码
public static void main(String[] args) throws InterruptedException {
// 创建线程池
ThreadPoolExecutor threadPoolExecutor =
new ThreadPoolExecutor(5, 5, 60,
TimeUnit.SECONDS, new LinkedBlockingQueue<>(100));
// 执行 n 次调用
for (int i = 0; i < 10; i++) {
// 执行任务
executeTask(threadPoolExecutor);
Thread.sleep(1000);
}
}
/**
* 线程池执行任务
* @param threadPoolExecutor 线程池
*/
private static void executeTask(ThreadPoolExecutor threadPoolExecutor) {
// 执行任务
threadPoolExecutor.execute(new Runnable() {
@Override
public void run() {
System.out.println("创建对象");
try {
// 创建对象(10M)
MyTask myTask = new MyTask();
// 存储 ThreadLocal
taskThreadLocal.set(myTask);
// 其他业务代码...
} finally {
// 释放内存
taskThreadLocal.remove();
}
}
});
}
}
以上程序的执行结果如下:

从上述结果可以看出我们只需要在 finally 中执行 ThreadLocal 的 remove 方法之后就不会在出现内存溢出的问题了。