介紹得非常詳細:
新生代回收:(復制算法)
在堆中,新生代主要存放的是哪些很快就會被GC回收掉的或者不是特別大的對象(是否設置了-XX:PretenureSizeThreshold 參數)。復制算法的新生代分為3個區:較大的Eden和兩個較小的Survivor(默認的Eden:Survivor = 8:1)。發生在新生代的GC為Minor GC 。在Minor GC時會將新生代中還存活着的對象復制進一個Survivor中,然后對Eden和另一個Survivor進行清理。所以,平常可用的新生代大小為Eden的大小+一個Survivor的大小。
老年代回收:(標記-清除算法/標記-整理算法)
老年代則是存放那些在程序中經歷了好幾次回收仍然還活着或者特別大的對象(是否設置了-XX:PretenureSizeThreshold 參數)。老年代采用的是標記-清除或者標記-整理算法,這兩個算法主要看虛擬機采用的哪個收集器,兩種算法的區別是:標記-清除可能會產生大量連續的內存碎片。在老年代中的GC則為Major GC。Major GC和Full GC會造成stop-the-world。
標記:(一致)遍歷GC Roots,將存活的對象標記
整理:移動所有存活對象,按照內存地址次序依次排列,將末端內存地址以后的內存全部回收
新生代進入老年代:
1.分配擔保機制:當Minor GC時,新生代存活的對象大於Survivor的大小時,這時一個Survivor裝不下它們,那么它們就會進入老年代。
2.如果設置了-XX:PretenureSizeThreshold3M 那么大於3M的對象就會直接就進入老年代。
3.在新生代的每一次Minor GC 都會給在新生代中的對象+1歲,默認到15歲時就會從新生代進入老年代,可以通過-XX:MaxTenuringThreshold來設置這個臨界點。
相比較而言,在老年代中的對象比新生代中的對象不易回收許多。
永久代回收:(即方法區回收)
JVM的方法區,也被稱為永久代。在這里都是放着一些被虛擬機加載的類信息,靜態變量,常量等數據。這個區中的東西比老年代和新生代更不容易回收。
效率:復制算法>標記/整理算法>標記/清除算法(此處的效率只是簡單的對比時間復雜度,實際情況不一定如此)。
內存整齊度:復制算法=標記/整理算法>標記/清除算法。
內存利用率:標記/整理算法=標記/清除算法>復制算法。
轉自:https://blog.csdn.net/qq_23835497/article/details/71696067