ThreadLocal變量保存在哪
存在線程中卵惦,Thread類中有個變量:
/* ThreadLocal values pertaining to this thread. This map is maintained
* by the ThreadLocal class. */
ThreadLocal.ThreadLocalMap threadLocals = null;
ThreadLocal為什么會有內(nèi)存泄漏
static class Entry extends WeakReference<ThreadLocal<?>> {
/** The value associated with this ThreadLocal. */
Object value;
Entry(ThreadLocal<?> k, Object v) {
super(k);
value = v;
}
}
ThreadLocalMap中的Entry,key是ThreadLocal的弱引用厂镇,value是外面保存進(jìn)來的變量。當(dāng)key在下次GC被回收后叁丧,value不會被回收。除非再次調(diào)用 get /set /remove方法岳瞭,最好的使用方法是每次用完后記得remove拥娄。
強(qiáng)、軟瞳筏、弱稚瘾、虛——引用
- 強(qiáng)引用
Object a = new Object(); 只要引用存在,垃圾回收器永遠(yuǎn)不會回收
- 軟引用
SoftReference姚炕,軟引用是用來描述一些還有用但并非必須的對象摊欠。對于軟引用關(guān)聯(lián)著的對象,在系統(tǒng)將要發(fā)生內(nèi)存溢出異常之前柱宦,將會把這些對象列進(jìn)回收范圍進(jìn)行第二次回收些椒。如果這次回收還沒有足夠的內(nèi)存,才會拋出內(nèi)存溢出異常掸刊。
- 弱引用
WeakReference免糕,GC回收時必回收
- 虛引用
一個對象是否有虛引用的存在,完全不會對其生存時間構(gòu)成影響,也無法通過虛引用來獲取一個對象的實例石窑。為一個對象設(shè)置虛引用關(guān)聯(lián)的唯一目的就是能在這個對象被收集器回收時收到一個系統(tǒng)通知牌芋。虛引用和弱引用對關(guān)聯(lián)對象的回收都不會產(chǎn)生影響,如果只有虛引用活著弱引用關(guān)聯(lián)著對象尼斧,那么這個對象就會被回收姜贡。它們的不同之處在于弱引用的get方法试吁,虛引用的get方法始終返回null,弱引用可以使用ReferenceQueue,虛引用必須配合ReferenceQueue使用棺棵。
jdk中直接內(nèi)存的回收就用到虛引用,由于jvm自動內(nèi)存管理的范圍是堆內(nèi)存熄捍,而直接內(nèi)存是在堆內(nèi)存之外(其實是內(nèi)存映射文件烛恤,自行去理解虛擬內(nèi)存空間的相關(guān)概念),所以直接內(nèi)存的分配和回收都是有Unsafe類去操作余耽,java在申請一塊直接內(nèi)存之后缚柏,會在堆內(nèi)存分配一個對象保存這個堆外內(nèi)存的引用,這個對象被垃圾收集器管理碟贾,一旦這個對象被回收币喧,相應(yīng)的用戶線程會收到通知并對直接內(nèi)存進(jìn)行清理工作。