Java中的內存分爲五個部分,分別是方法區、虛擬機棧、堆、程序計數器和本地方法區。算法
存放運行時加載的類信息、靜態變量、常量等信息。緩存
存放對象的引用、方法的返回地址等。 每一個線程都有一個棧。spa
主要存放對象的實例。 全部線程共享同一個堆。線程
存放運行程序的行數信息。code
和方法區相似,但存放的native方法的相關內容。對象
清理的內容主要是存在於堆和方法區的內容。生命週期
方法一:引用計數:當一個對象被引用次數+1,引用釋放時次數-1,=0時便可回收。可是存在互相引用問題,會致使沒法回收。 方法二:可達性分析:當一個對象沒有經過引用鏈和GC roots相連的時候,就表示已經沒有用,能夠回收了。 GC roots有哪些? - 虛擬機(棧幀中的本地變量表)中引用的對象 - 方法區中類靜態屬性引用的對象 - 方法區中常量引用的對象 - 本地方法棧中JNI(即通常說的native方法)中引用的對象隊列
1. 串行回收 2. 並行回收 3. 與用戶線程同存的回收 4. G1回收
即便OOM也不會被清理。對對象的引用默認就是這種方式。例如,Object o = new Object(); 【FinalReference類不是public的,沒辦法直接用】
當內存不足的時候會被清理。比較適用於緩存。
當沒有再被引用時,隨時都有可能被清理。 這裏寫一個小例子來展現弱引用的效果。 public static void main(String[] args) throws InterruptedException { AtomicInteger integer = new AtomicInteger(12); WeakReference<AtomicInteger> reference = new WeakReference<>(integer); System.out.println("正在使用時,reference.get()="+reference.get()); System.gc(); System.out.println("引用的對象還引用着,reference.get()="+reference.get()); integer = null; System.out.println("引用的對象置空了,可是還未進行垃圾回收,reference.get()="+reference.get()); System.gc(); System.out.println("引用的對象置空了,垃圾回收後,reference.get()="+reference.get()); } 運行結果: 正在使用時,reference.get()=12 引用的對象還引用着,reference.get()=12 引用的對象置空了,可是還未進行垃圾回收,reference.get()=12 引用的對象置空了,垃圾回收後,reference.get()=null 能夠看到: 被弱引用的對象在尚未結束生命週期時,即便gc也不會被清理; 當將被弱引用的對象生命週期結束(=null)時,當即去引用裏get(),仍然能夠拿到,證實了這一刻還未被回收; 再次調用gc(),這時再get()就已經沒有了。 若是把WeakReference換成SoftReference,那麼最後一次get的時候就不會是null。
相似於弱引用,可是在被即將收集時,會被放入一個引用隊列。用戶能夠查詢引用隊列看是否該對象會被清理,進行一些額外的操做。