1.四種引用類型
1)強引用(Strong Reference) 就是為剛被new出來的對象所加的引用辞色,它的特點就是骨宠,生命周期長,不會因為內(nèi)存緊張而被回收淫僻。
Object obj = new Object(); // 強引用
Object objRef = obj; // 強引用
2)軟引用(Soft Reference) 聲明為軟引用的類诱篷,是可被回收的對象壶唤,如果JVM內(nèi)存并不緊張雳灵,這類對象可以不被回收,如果內(nèi)存緊張闸盔,則會被回收悯辙。此處有一個問題,既然被引用為軟引用的對象可以回收迎吵,為什么不去回收呢躲撰?其實我們知道,Java中是存在緩存機制的击费,就拿字面量緩存來說拢蛋,有些時候,緩存的對象就是當前可有可無的蔫巩,只是留在內(nèi)存中如果還有需要谆棱,則不需要重新分配內(nèi)存即可使用快压,因此,這些對象即可被引用為軟引用垃瞧,方便使用蔫劣,提高程序性能。
Object obj = new Object(); // 強引用
Object objRef = new SoftReference(obj); // 軟引用
if (null != objRef) {
obj = objRef.get(); // 獲取對象个从,如果對象已被回收脉幢,obj為null
}
3)弱引用(Weak Reference) 弱引用的對象就是一定需要進行垃圾回收的,不管內(nèi)存是否緊張嗦锐,當進行GC時嫌松,標記為弱引用的對象一定會被清理回收。
Object obj = new Object(); // 強引用
Object objRef = new WeakReference(obj); // 弱引用
if (null != objRef) {
obj = objRef.get(); // 獲取對象意推,如果對象已被回收豆瘫,obj為null
}
4)虛引用(Phantom Reference) 虛引用弱的可以忽略不計,JVM完全不會在乎虛引用菊值,其唯一作用就是做一些跟蹤記錄外驱,輔助finalize函數(shù)的使用。
Object obj = new Object(); // 強引用
ReferenceQueue rq = new ReferenceQueue();
PhantomReference objRef= new PhantomReference(obj, rq);
objRef.get(); // always null
2.垃圾回收機制
這邊就簡單說下Android目前的垃圾回收機制腻窒。 垃圾回收機制用于回收heap中的不再使用的對象昵宇,不同的JVM,垃圾回收機制也有所不同儿子。JVM通常會使用Generation機制進行垃圾回收瓦哎,分為三代:年輕代,年老代和永久代柔逼。 一般新對象都會分派到年輕代中蒋譬,如局部對象等,大部分對象也會在年輕代中被回收愉适。年輕代中有3個內(nèi)存塊犯助,其中From和To是2個survivor內(nèi)存塊,F(xiàn)rom存放從Eden中存活下來的對象维咸,To存放從From存活下來的對象剂买,年輕代中未回收的對象會被復(fù)制到年老代中。每當內(nèi)存塊滿的時候就會進行內(nèi)存回收癌蓖,年輕代中的內(nèi)存回收只針對當前內(nèi)存塊進行回收瞬哼,年老代的內(nèi)存回收針對整個heap回收,年老代的內(nèi)存回收會比較慢租副。 經(jīng)典的垃圾回收算法是引用計數(shù)算法坐慰,iOS的OC正是采用此算法。它為每個對象添加一個引用計數(shù)器用僧,每被引用一次结胀,計數(shù)器加1两残,失去引用,計數(shù)器減1把跨,當計數(shù)器在一段時間內(nèi)保持為0時人弓,該對象就認為是可以被回收得了。但是着逐,這個算法有明顯的缺陷:當兩個對象相互引用崔赌,但是二者已經(jīng)沒有作用時,按照常規(guī)耸别,應(yīng)該對其進行垃圾回收健芭,但是其相互引用,又不符合垃圾回收的條件秀姐,因此無法完美處理這塊內(nèi)存清理慈迈,因此Dalvik并沒有采用引用計數(shù)算法來進行垃圾回收。而是采用一個叫:根搜索算法省有,如下圖:基本思想就是:從一個叫GC Roots的對象開始痒留,向下搜索,如果一個對象不能到達GC Roots對象的時候蠢沿,說明它已經(jīng)不再被引用伸头,即可被進行垃圾回收(此處 暫且這樣理解,其實事實還有一些不同舷蟀,當一個對象不再被引用時恤磷,并沒有完全“死亡”,如果類重寫了finalize()方法野宜,且沒有被系統(tǒng)調(diào)用過扫步,那么系統(tǒng)會調(diào)用一次finalize()方法,以完成最后的工作匈子,在這期間河胎,如果可以將對象重新與任何一個和GC Roots有引用的對象相關(guān)聯(lián),則該對象可以“重生”旬牲,如果不可以仿粹,那么就說明徹底可以被回收了)搁吓,如上圖中的Object5原茅、Object6、Object7堕仔,雖然它們3個依然可能相互引用擂橘,但是總體來說,它們已經(jīng)沒有作用了摩骨,這樣就解決了引用計數(shù)算法無法解決的問題通贞。 GCRoot 都有哪些朗若?
1、 Class:由系統(tǒng)的類加載器加載的類對象
2昌罩、 Static Fields
3哭懈、 Thread:活著的線程
4、 Stack Local: java方法的局部變量或參數(shù)
5茎用、 JNI Local: JNI方法中的局部引用
6遣总、 JNI Global: 全局的JNI引用
7、 Monitor used: 用于同步的監(jiān)控對象