內(nèi)存泄露:
指程序中己動(dòng)態(tài)分配的堆內(nèi)存由于某種原因程序未釋放或無法釋放氯葬,造成系統(tǒng)內(nèi)存的浪費(fèi),導(dǎo)致程序運(yùn)行速度減慢甚至系統(tǒng)崩潰等嚴(yán)重后果恬叹。
這里我們思考一個(gè)問題:ThreadLocal使用到了弱引用,是否意味著不會(huì)存在內(nèi)存泄露呢?
首先來說执赡,如果把ThreadLocal置為null,那么意味著Heap中的ThreadLocal實(shí)例不在有強(qiáng)引用指向函筋,只有弱引用存在沙合,因此GC是可以回收這部分空間的,也就是key是可以回收的驻呐。但是value卻存在一條從Current Thread過來的強(qiáng)引用鏈灌诅。因此只有當(dāng)Current Thread銷毀時(shí),value才能得到釋放含末。
因此猜拾,只要這個(gè)線程對象被gc回收,就不會(huì)出現(xiàn)內(nèi)存泄露佣盒,但在threadLocal設(shè)為null和線程結(jié)束這段時(shí)間內(nèi)不會(huì)被回收的挎袜,就發(fā)生了我們認(rèn)為的內(nèi)存泄露。最要命的是線程對象不被回收的情況肥惭,比如使用線程池的時(shí)候盯仪,線程結(jié)束是不會(huì)銷毀的,再次使用的蜜葱,就可能出現(xiàn)內(nèi)存泄露全景。
那么如何有效的避免呢?
事實(shí)上牵囤,在ThreadLocalMap中的set/getEntry方法中爸黄,會(huì)對key為null(也即是ThreadLocal為null)進(jìn)行判斷滞伟,如果為null的話,那么是會(huì)對value置為null的炕贵。我們也可以通過調(diào)用ThreadLocal的remove方法進(jìn)行釋放梆奈!
假設(shè)垃圾收集器在某個(gè)時(shí)間點(diǎn)決定一個(gè)對象是弱可達(dá)的(weakly reachable)(也就是說當(dāng)前指向它的全都是弱引用),這時(shí)垃圾收集器會(huì)清除所有指向該對象的弱引用称开,然后垃圾收集器會(huì)把這個(gè)弱可達(dá)對象標(biāo)記為可終結(jié)(finalizable)的亩钟,這樣它們隨后就會(huì)被回收。