天天看點

Java運作時資料區域解析(二)

Java運作時資料區域解析(二)

Java運作時資料區域解析(二)

Java虛拟機在Java程式執行的過程中會把其管理的記憶體分為若幹個不同的資料區域。他們有着各自不同的特性。這些區域有的随着虛拟機程序的啟動而一直存在,有的和使用者線程同生共死。

Java運作時資料區域解析(二)

方法區與堆一樣,是各個線程共享的,用于存儲被虛拟機加載的類型資訊、常量、靜态變量、即時編譯器編譯後的代碼緩存等資料。

方法區是堆的一個邏輯部分,原則上如何實作方法區屬于虛拟機實作細節,不受《Java虛拟機規範》管束,不要求統一。

JDK7及之前使用永久代實作方法區,JDK8之後完全廢棄了方法區e概念,改用在本地記憶體中實作的“元空間”來代替。

當方法區無法滿足新的記憶體配置設定需求時,将抛出OutOfMemoryError異常。

運作時常量池是方法區的一部分。Class檔案中除了有類的版本、字段、方法、接口等描述資訊外,還有一項資訊是常量池表,用于存放編譯期生成的各種字面量和符号引用,這部分在類加載後存放到方法區的運作時常量池中。

一般來說,除了符号引用,由它翻譯而來的直接引用也會存儲在運作時常量池中。

運作時常量池相比Class檔案常量池的一個重要特征是具備動态性,Java語言并不要求常量隻有在編譯期才能産生,也就是說并非預置入Class檔案中常量池的内容才能進入方法區運作時常量池,運作期間也可以将新的常量放入池中。String類的intern方法就是利用這種特性編寫的。

直接記憶體并不是虛拟機運作時資料區的一部分,也不是《Java虛拟機規範》中定義的記憶體區域。

在JDK1.4中新加入了NIO類(New Input/Output),引入了一種基于通道與緩沖區的IO方式,它可以使用Native函數庫直接配置設定堆外記憶體,然後通過一個存儲在Java堆中的DirectByteBuffer對象作為這塊記憶體的引用進行操作。這樣能在一些場景中顯著提高性能,因為避免了Java堆和Native堆之間來回複制資料。

顯然,直接記憶體的配置設定不會受到Java堆記憶體大小的限制。