簡述Java垃圾回收機制
在java中蒜魄,程序員是不需要顯示的去釋放一個對象的內(nèi)存的扔亥,而是由虛擬機自行執(zhí)行。在JVM中谈为,有一個垃圾回收線程旅挤,它是低優(yōu)先級的,在正常情況下是不會執(zhí)行的伞鲫,只有在虛擬機空閑或者當前堆內(nèi)存不足時粘茄,才會觸發(fā)執(zhí)行,掃面那些沒有被任何引用的對象秕脓,并將它們添加到要回收的集合中柒瓣,進行回收。
優(yōu)點:JVM的垃圾回收器都不需要我們手動處理無引用的對象了吠架,這個就是最大的優(yōu)點
缺點:程序員不能實時的對某個對象或所有對象調(diào)用垃圾回收器進行垃圾回收
垃圾收集GC(Gabage Collection)芙贫,內(nèi)存處理是編程人員容易出現(xiàn)問題的地方,忘記或者錯誤的內(nèi)存回收會導(dǎo)致程序或系統(tǒng)的不穩(wěn)定甚至崩潰傍药,Java 提供的 GC功能可以自動監(jiān)測對象是否超過作用域從而達到自動回收內(nèi)存的目的磺平,Java 語言沒有提供釋放已分配內(nèi)存的顯示操作方法。
垃圾回收器的原理是什么拐辽?
對于GC來說拣挪,當程序員創(chuàng)建對象時,GC就開始監(jiān)控這個對象的地址俱诸、大小以及使用情況菠劝。通常,GC采用有向圖的方式記錄和管理堆(heap)中的所有對象睁搭。通過這種方式確定哪些對象是"可達的"闸英,哪些對象是"不可達的"。當GC確定一些對象為"不可達"時介袜,GC就有責任回收這些內(nèi)存空間。
有什么辦法手動進行垃圾回收出吹?
程序員可以手動執(zhí)行System.gc()遇伞,通知GC運行,但是Java語言規(guī)范并不保證GC一定會執(zhí)行
JVM中怎么判斷對象是可以被回收的捶牢?
垃圾收集器在做垃圾回收的時候鸠珠,首先需要判定的就是哪些內(nèi)存是需要被回收的,哪些對象是存活的秋麸,是不可以被回收的渐排;哪些對象已經(jīng)死掉了,需要被回收灸蟆。一般有兩種方法來判斷:
引用計數(shù)器法:為每個對象創(chuàng)建一個引用計數(shù)驯耻,有對象引用時計數(shù)器 +1,引用被釋放時計數(shù)-1,當計數(shù)器為 0 時就可以被回收可缚。它有一個缺點不能解決循環(huán)引用的問題霎迫;(python中使用)
可達性分析算法:從 GC Roots 開始向下搜索,搜索所走過的路徑稱為引用鏈帘靡。當一個對象到 GC Roots 沒有任何引用鏈相連時知给,則證明此對象是可以被回收的。(Java中使用)
可以作為GC Root的對象:
虛擬機棧(棧幀中的本地變量表)中引用的對象描姚。
方法區(qū)中類靜態(tài)屬性引用的對象涩赢。
方法區(qū)中常量引用的對象。
本地方法棧中 Native 方法引用的對象轩勘。
JVM 垃圾回收算法有哪些筒扒?
標記-清除算法:標記無用對象,然后進行清除回收赃阀。缺點:效率不高霎肯,無法清除垃圾碎片。
復(fù)制算法:按照容量劃分二個大小相等的內(nèi)存區(qū)域榛斯,當一塊用完的時候?qū)⒒钪膶ο髲?fù)制到另一塊上观游,然后再把已使用的內(nèi)存空間一次清理掉。缺點:內(nèi)存使用率不高驮俗,只有原來的一半懂缕。
標記-整理算法:標記無用對象,讓所有存活的對象都向一端移動王凑,然后直接清除掉端邊界以外的內(nèi)存搪柑。
分代算法:根據(jù)對象存活周期的不同將內(nèi)存劃分為幾塊,一般是新生代和老年代索烹,新生代基本采用復(fù)制算法工碾,老年代采用標記整理算法。