1.引用計數算法
引用計數(Reference Counting)算法是每個對象計算指向它的指針的數量,當有一個指針指向自己時計數值加1;當刪除一個指向自己的指針時,計數值減1,如果計數值減為0,說明已經不存在指向該對象的指針了,所以它可以被安全的銷毀了。
引用計數的明顯缺點:無法處理環形引用
算法特點
-
需要單獨的字段存儲計數器,增加了存儲空間的開銷;
-
每次賦值都需要更新計數器,增加了時間開銷;
-
垃圾對象便於辨識,只要計數器為0,就可作為垃圾回收;
-
及時回收垃圾,沒有延遲性;
-
不能解決循環引用的問題;
2. 標記-清除(Mark-Sweep)算法
例如: Lua就采用了mark-sweep的垃圾回收機制
標記-清除(Mark-Sweep)算法依賴於對所有存活對象進行一次全局遍歷來確定哪些對象可以回收,遍歷的過程從根出發,找到所有可達對象,除此之外,其它不可達的對象就是垃圾對象,可被回收。整個過程分為兩個階段:標記階段找到所有存活對象;清除階段清除所有垃圾對象。

優點
-
相比較引用計數算法,標記-清除算法可以非常自然的處理環形引用問題,
-
另外在創建對象和銷毀對象時時少了操作引用計數值的開銷
缺點
-
標記-清除算法是一種“停止-啟動”算法,在垃圾回收器運行過程中,應用程序必須暫時停止
-
標記-清除算法在標記階段需要遍歷所有的存活對象,會造成一定的開銷
-
在清除階段,清除垃圾對象后會造成大量的內存碎片。
3. 標記-縮並(Mark-Compact)算法(解決內存碎片)
整個過程可以描述為
- 標記所有的存活對象;
- 通過重新調整存活對象位置來縮並對象圖;
- 更新指向被移動了位置的對象的指針。
標記-壓縮算法最大的難點在於如何選擇所使用的壓縮算法,如果壓縮算法選擇不好,將會導致極大的程序性能問題,如導致Cache命中率低等。一般來說,根據壓縮后對象的位置不同,壓縮算法可以分為以下三種:
-
任意:移動對象時不考慮它們原來的次序,也不考慮它們之間是否有互相引用的關系。
-
線性:盡可能的將原來的對象和它所指向的對象放在相鄰位置上,這樣可以達到更好的空間局部性。
-
滑動:將對象“滑動”到堆的一端,把存活對象之間的自由單元“擠出去”,從而維持了分配時的原始次序。
4. 節點拷貝(Copying)算法(解決內部碎片)
節點拷貝算法是把整個堆分成兩個半區(From,To), GC的過程其實就是把存活對象從一個半區From拷貝到另外一個半區To的過程,而在下一次回收時,兩個半區再互換角色。在移動結束后,再更新對象的指針引用
參考
http://blog.csdn.net/sinat_36246371/article/details/53002209

簡單,高效,空間換時間。
5 Generational Collection(分代收集)算法
分代收集算法是目前大部分JVM的垃圾收集器采用的算法。它的核心思想是根據對象存活的生命周期將內存划分為若干個不同的區域。一般情況下將堆區划分為老年代(Tenured Generation)和新生代(Young Generation),老年代的特點是每次垃圾收集時只有少量對象需要被回收,而新生代的特點是每次垃圾回收時都有大量的對象需要被回收,那么就可以根據不同代的特點采取最適合的收集算法。
目前大部分垃圾收集器對於新生代都采取Copying算法,因為新生代中每次垃圾回收都要回收大部分對象,也就是說需要復制的操作次數較少,但是實際中並不是按照1:1的比例來划分新生代的空間的,一般來說是將新生代划分為一塊較大的Eden空間和兩塊較小的Survivor空間,每次使用Eden空間和其中的一塊Survivor空間,當進行回收時,將Eden和Survivor中還存活的對象復制到另一塊Survivor空間中,然后清理掉Eden和剛才使用過的Survivor空間。
而由於老年代的特點是每次回收都只回收少量對象,一般使用的是Mark-Compact算法。
注意,在堆區之外還有一個代就是永久代(Permanet Generation),它用來存儲class類、常量、方法描述等。對永久代的回收主要回收兩部分內容:廢棄常量和無用的類。
原文:https://doctording.blog.csdn.net/article/details/53728388?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&dist_request_id=6b460756-003e-4553-a15f-de282251b1c3&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control
6、JVM不同的版本垃圾回收機制不一樣,jdk1.7和1.8新版本和老版本區別
jdk1.7和1.8舊版本Parallel Old,(老年代)
jdk1.7和1.8新版本Parallel Scavenge,(新生代)
Parallel Old 收集器
Parallel Scavenge收集器的老年代版,使用多線程與標記–整理算法。這個收集器在jdk1.6中才開始提供的,直到Parallel Old 收集器出現后,“吞吐量優先”收集器終於有了比較名副其實的應用組合,在注重吞吐量以及CPU資源敏感的場合,都可以優先考慮Parallel Scavenge加 Parallel Old收集器
Parallel Scavenge收集器
Parallel Scavenge收集器是一個新生代的手機器,使用的是復制算法的收集器,而且也是多線程的收集器。。Parallel Scavenge收集器,目標達到一個可控制的吞吐量,使用-XX:MaxGCPauseMillus參數控制垃圾停頓時間,使用-XX:GCTimeRatio參數控制吞吐量。Parallel Scavenge收集器設置-XX:UseAdaptiveSizePolicy參數,虛擬機會根據當前系統的運行情況收集性能監控信息,動態調整這些參數以提供最合適的停頓時間或者最大吞吐量(GC自使用的調節策略)。
自適應調節策略也是Parallel Scavenge收集器和ParNew收集器一個重要的區別。
7 、需要了解
1、GC 是什么? 為什么要有GC
GC 是垃圾收集的意思,內存處理是程序員人員容易出現問題的地方,忘記或者錯誤的內存回收會導致程序或系統的不穩定甚至崩潰,Java 提供的GC 功能可以自動監測對象是否超過作用域從而達到自動回收內存的目的,Java 語言沒有提供釋放已分配內存的顯示操作方法。Java 程序員不用擔心內存管理,因為垃圾收集器會自動進行管理。要請求垃圾收集,可以調用下面的方法之一:
System.gc() 或Runtime.getRuntime().gc()
2、垃圾回收器的基本原理是什么
對於GC 來說,當程序員創建對象時,GC 就開始監控這個對象的地址、大小以及使用情況。通常,GC 采用有向圖的方式記錄和管理堆(heap)中的所有對象。通過這種方式確定哪些對象是"可達的",哪些對象是"不可達的"。當GC 確定一些對象為"不可達"時,GC 就有責任回收這些內存空間。
3、有什么辦法主動提醒虛擬機進行垃圾回收器回收垃圾嗎
可以,可以手動執行System.gc() 或 Runtime.getRuntime().gc(),通知GC 運行,但是Java 語言規范並不保證GC 一定會執行。
4、垃圾回收機制回收的是什么
垃圾回收機制的目標是回收無用對象的內存空間(記住:不是對象),這些內存空間是JVM堆內存的內存空間。垃圾回收只回收內存資源,對於那些物理資源,如數據庫連接,Socket,I/O流等資源無能無能為力,我們要自己關閉回收。
原文鏈接:https://blog.csdn.net/weixin_43122090/article/details/103652073
