ThreadLocal分析

ThreadLocal使用中,通过规范,使用后调用remove,但到底什么是内存泄漏,以及具体细节不清楚,本次看码出高效又提到了,所以想分析一下

  如果配置高,请求小的情况下 还是很难内存泄漏的。

  首先ThreadLocalMap的设计中已经考虑到这种情况,在ThreadLocalget(),set(),remove()的时候都会清除线程ThreadLocalMap里所有keynullvalue。所以每次请求会把之前请求调用完成的 key=null,valu的remove

  但当数据大、请求时长比较高的情况下,可能就会出现 OutOfMemoryError: Java heap space

  图中一个案例  我们把 VM options 设置 -Xmx200M -Xms200M,如果不自己手动remover 就会oom

  场景:为了复用,自己创建了一个线程池,由于疏忽每次结束,没有remove,那本质上,由于线程没终结,哪怕gc后 key为null,但value是有值的,后期这种就类型Linux的僵尸进程 占用资源,但不会被调用  ThreadLocalMap的设计中清楚线程是指清楚已经销毁的线程,而线程池中必然是有持久的核心线程数,【排除一种情况:设置allowCoreThreadTimeOut(true)时,线程池中corePoolSize线程空闲时间达到keepAliveTime也将关闭,但一般这种情况频繁开销也没意义】

 1 public class Main {
 2 
 3     static ThreadLocal threadLocal=new ThreadLocal();
 4 
 5     public static void main(String[] args) throws InterruptedException {
 6         
 7         // thradLocal中存储了100M的数据,最大堆大小设置为200M.
 8         threadLocal.set(new byte[1024 * 1024 * 100]);
 9         threadLocal = null;
10         
11         System.gc();
12         // 主动调用 threadLocal.remove();
13         // threadLocal.remove();
14         // threadLocal会被回收
15         
16         byte[][] bytes = new byte[20][];
17         for (int i = 0; i < 16; i++) {
18             bytes[i] = new byte[1024 * 1024 * 10];
19             System.out.println((i + 1) * 10 + "Mb allocated..");
20         }
21         
22         System.out.println("finished..");
23     }
24 }

目前内功不强的我,是比较注意这些规范的,先把一些错误避免了,后期再进行修炼

posted @ 2022-02-15 11:13  铁柱97  阅读(31)  评论(0)    收藏  举报