內容稍微變化了一點,主要講解JVM中GC相關的部分
PPT:JVM_GC.pdf
示例源碼:src_jvm_gc.rar
講稿:
==========
GC
1.什么是GC:
1)釋放不再使用的內存對象以回收內存空間
2)壓縮內存碎片
2.為什么要讓JVM做GC,而不是程序員來做?
1)把開發(fā)人員從管理內存中解放出來,提高生產率
2)安全角度考慮,不會由于失誤/故意錯誤釋放內存帶來潛在的安全問題
3)弊端:額外地占用CPU,且對于程序員來說”難于”控制
引用計數(shù)收集器:
start:當創(chuàng)建對象,并且指向該對象的引用被分配給一個變量,這個對象的引用計數(shù)被置為1
其他變量被賦值為對這個對象引用時,i++
一個對象引用超過生存期或者被設置成一個新值時,i–
計數(shù)為0的對象就可以被收集
當收集的時候,該對象所引用的對象計數(shù)i–
優(yōu)點:速度快,交織在程序運行之中
缺點:無法檢測出循環(huán)引用
跟蹤收集器:
從根結點開始跟蹤,對所有跟蹤到的對象以某種方式(和實現(xiàn)有關)打上標記,跟蹤結束時,就可以對沒打上標記的對象實現(xiàn)收集
優(yōu)點:可以回收循環(huán)引用
缺點:回收的時候長時間獨占CPU
問題:什么是根結點
根結點:
和實現(xiàn)有關:總的來說有以下幾個方面:
1.局部變量,操作數(shù)棧(參數(shù))
2.常量池中對象:字符串,類名,接口名…
3.JNI調用,沒有被釋放的
壓縮收集器:
把標記為活動的對象從原來的區(qū)域越過空閑區(qū)移動到堆的另一端
問題:更新移動的對象要更新所有的指針(以用于清理)
解決:有些JVM實現(xiàn)做了一層 間接對象引用層 (不完美,每次取對象都要多一個步驟)
拷貝收集器:
有兩個內存區(qū)域
把標記為活動的對象從原來的區(qū)域拷貝到另一個區(qū)域
同一時間只有一個區(qū)域在使用
優(yōu)點:在使用的時候才更新指針
缺點:內存使用率降低
finalize
時機:對象被回收時
流程:收集器第一遍掃描出不再被引用的對象
調用他們的finalize方法,此時程序員可以實現(xiàn)finalize方法做清理工作,可以復活這個對象
收集器第二遍掃描,只掃描不再被引用的對象,對沒復活的對象做清理
jdk1.2以前:可觸及,可復活,不可觸及
可觸及:從根結點開始跟蹤可以觸及到
可復活:從根結點跟蹤不可觸及,但在自己或者別人的finalize方法里重新使該對象可觸及
不可觸及:finalize方法后也不可觸及
jdk1.2以后:軟引用,弱引用,影子引用
軟引用:做cache
弱引用,做映射:初始化實例時默認配置,配置修改時可以通知,如果實例已經不再使用,就不通知
影子引用:處理收集時的后續(xù)操作,類比finalize,初始化時要增加一個ReferenceQueue隊列參數(shù)
==========
文章來源:http://lookis.me/?p=32