JVM堆內存結構:
JVM堆內存可分為三個區域:新生代(Young Generation)、年老代(Tenured Generation,也叫做Old Generation)和永久代(Permanent Generation,也叫做Method Area)。其中,新生代又分為一個Eden區和兩個Survivor區。
Eden區:是新生代中對象最初被創建的地方。當新創建一個Java對象時,該對象會被分配在Eden區。如果Eden區無法容納新創建的Java對象,就會觸發一次Minor GC(年輕代垃圾收集),將Eden區和Survivor區中沒有被引用的對象清除,而仍存活的對象則會被移至Survivor區。
Survivor區:當Java對象在Eden區中經過一次Minor GC后,如果在Survivor區中已經存在一份相同的對象,就會將該對象復制到Survivor區,同時更新該對象的引用計數器。Survivor區是一塊大小較小的區域,通常分為兩個大小相等的區域。每次Minor GC后,Survivor區中存活的Java對象都會被復制到另一個空區,同時清空這個區域。Survivor區的主要作用是存放年輕代中從Eden區中被復制過來的存活對象,以及在Minor GC時被轉移到另一個Survivor區中的存活對象。
年老代:當Java對象在Survivor區中經過多次復制后仍然存活,它們就會被晉升到年老代。年老代是專門存放Java長生命周期對象的區域,因此也被稱為Old Generation。當年老代區域無法容納新創建的Java對象時,就會發生一次Full GC(全局垃圾收集),將整個堆內存中無用的對象都清除掉。
永久代:是一塊專門存儲Java類(Class)信息的區域,也被稱為Method Area。在Java 8及以后的版本中,永久代已經被Metaspace取代。
YGC和FGC的原理:
在Java的內存管理中,每一次GC都有一個主要的目標,就是清除無用的對象,重新回收內存空間。另外,JVM的內存管理還存在一些通用的策略,比如對象的創建、移動和回收等。
YGC(年輕代GC):
在JVM中,當Eden區和Survivor區中沒有存活對象時,就會進行一次YGC。YGC的主要目標是清除年輕代中的無用對象,將存活對象移動到Survivor區。在經過一定時間和一定次數的YGC后,年輕代中的存活對象會被晉升到年老代。這是因為年老代中的對象生命周期較長,因此在Full GC時才會被收集。
FGC(Full GC):
在JVM中,當年老代區域無法容納新創建的Java對象時,就會發生一次Full GC,將整個堆內存中無用的對象都清除掉。Full GC清理的對象范圍包括年輕代、年老代和永久代。Full GC會帶來較長的停頓時間,因此需要盡可能地避免觸發Full GC。
總結:
YGC主要是針對年輕代和Survivor區進行垃圾回收的,而FGC則是對整個堆內存進行垃圾回收的。它們的共同目標都是將無用的對象從內存中清理出去,釋放內存空間,以便程序能夠更加高效地運行。