當一個對象的引用不在使用,但仍占用內存空間時,則被認為是垃圾對象。
二、怎么判斷垃圾對象目前java中可作為GC Root的對象有
① 虛擬機棧中引用的對象(本地變量表)
②方法區中靜態屬性引用的對象
③ 方法區中常量引用的對象
④本地方法棧中引用的對象(Native對象)
三、什么時候進行垃圾回收 1、JVM自己決定什么時候垃圾回收(由四給出的算法機制決定)。 2、程序員人為的觸發System.gc()方法,向系統發出垃圾回收請求,但最終是否回收,由系統決定。 注意:Java提供finalize()方法,為了釋放“特殊”內存區域(非new獲得的區域),Java允許類定義一個finalize()方法,垃圾回收器釋放對象時,將首先調用其finalize()方法。標記-清除算法采用從根集合進行掃描,對存活的對象對象標記,標記完畢后,再掃描整個空間中未被標記的對象,進行回收。標記-清除算法不需要進行對象的移動,并且僅對不存活的對象進行處理,在存活對象比較多的情況下極為高效,但由于標記-清除算法直接回收不存活的對象,因此會造成內存碎片!
2、復制算法
復制算法采用從根集合掃描,并將存活對象復制到一塊新的,沒有使用過的空間中,這種算法當控件存活的對象比較少時,極為高效,但是帶來的成本是需要一塊內存交換空間用于進行對象的移動。
3、標記-整理算法
標記-整理算法采用標記-清除算法一樣的方式進行對象的標記,但在清除時不同,在回收不存活的對象占用的空間后,會將所有的存活對象往左端空閑空間移動,并更新對應的指針。標記-整理算法是在標記-清除算法的基礎上,又進行了對象的移動,因此成本更高,但是卻解決了內存碎片的問題。
4、基于新生代---年老代的算法
JVM將堆分為Young區、Old區和Perm區 Yong區:又分為Eden區和兩個Survivor區,新創建的對象都在Eden區,當Eden區滿時,觸發minor GC將Eden區仍存活的對象復制到一個Survivor區,另一個Survivor區存活的對象也復制到這個Suevivor區,為了保證始終有一個Survivor區是空的。 Old區:存放的Young區的Survivor滿后,又有對象要加入Survivor區,則GC收集器將Survivor區的對象直接放到Old區。如果Survivor區中對象足夠老,也存放到Old區。如果Old區滿了,則觸發Full GC,回收整個堆內存。 Perm區:存放的主要是類對象,如果一個類被頻繁的加載,也會導致Perm區滿,Perm區回收也是Full GC觸發。
新聞熱點
疑難解答