一、內存分配與回收
JVM是Java虛擬機的縮寫,是Java語言最重要的一部分,是一個虛擬的計算機。當Java程序運行時,JVM會為程序分配一塊內存,這塊內存被稱為JVM的堆內存。當Java程序創建對象時,編譯器會把變數名解析為對對象的引用。JVM會通過循環遍歷可達對象的鏈表,在你不需要使用這些對象時回收它們佔用的內存。
二、JVM分區與GC演算法
JVM把堆分成了新生代和老年代兩個區域。新生代主要用於存放新創建的對象,老年代用於存放已經存活了一段時間的對象。JVM使用不同的垃圾回收演算法來回收不同的分區空間。
三、JVM分區詳解
在JVM里,堆分為兩塊區域:新生代和老年代。新生代又被分為兩塊區域:Eden空間和兩塊Survivor空間。新創建的對象首先會被分配到Eden空間中,當Eden空間滿時,JVM的垃圾回收器會掃描這些存活的對象,將它們複製到一個Survivor空間中。Survivor空間也被JVM分為了兩個區域。垃圾回收器會不斷地掃描這些對象,直到它們被放到老年代。
老年代主要用於存儲一些生命周期比較長的對象,比如靜態變數和常量池。老年代中存儲的對象比新生代中存儲的對象生命周期要長,JVM使用了不同的回收演算法來處理老生代的垃圾回收。
四、新生代分區詳解
新生代內存分為Eden區、Survivor區0和Survivor區1三個部分。其中Eden區主要用於存放新創建的對象,Survivor區用於存放從Eden區中複製過來並經過了一次GC仍然存活的對象。這些對象將會在Survivor的兩個空間中來回移動,最終被選出即將要晉陞到老生代的對象放置在Survivor區1中。
public class ObjectDemo{ public static void main(String[] args){ ObjectDemo obj1, obj2, obj3; obj1 = new ObjectDemo(); obj2 = new ObjectDemo(); obj3 = new ObjectDemo(); System.out.println("ObjectDemo 創建了3個實例"); } }
五、老生代分區詳解
老生代存儲的對象生命周期比新生代中的對象要長得多,這裡主要存放一些生命周期比較長的對象,比如靜態變數和常量池。老年代的垃圾回收一般是使用標記-清除演算法,並且在清除後會產生大量的內存碎片。為了減少內存碎片的產生,JVM將老生代分為了不同的區域,每個區域內都是滿足連續內存的。當某個區域內的內存使用完時,會把其中的存活對象移到其他區域中,並且在這個過程中會進行壓縮,消除內存碎片問題。
public class ObjectDemo{ public static void main(String[] args){ ObjectDemo obj1 = new ObjectDemo(); ObjectDemo obj2 = new ObjectDemo(); System.gc(); System.out.println("第一次gc完成"); ObjectDemo obj3 = new ObjectDemo(); ObjectDemo obj4 = new ObjectDemo(); obj3 = null; obj4 = null; System.gc(); System.out.println("第二次gc完成"); } }
六、永久代與元空間
在JDK8之前,Java虛擬機的永久代是用於存儲虛擬機自身的類元數據的區域,並且這個區域是非常少被使用到的。而在JDK8之後,永久代被徹底移除了,取而代之的是元空間,它是使用本地內存來存儲類元數據,因為它不再是虛擬機內部的一塊區域了。元空間內存使用的變化和永久代有些不同,只需要設置一個大小上限就可以了。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/191130.html