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

如果配置高,请求小的情况下 还是很难内存泄漏的。
首先ThreadLocalMap的设计中已经考虑到这种情况,在ThreadLocal的get(),set(),remove()的时候都会清除线程ThreadLocalMap里所有key为null的value。所以每次请求会把之前请求调用完成的 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 }
目前内功不强的我,是比较注意这些规范的,先把一些错误避免了,后期再进行修炼

浙公网安备 33010602011771号