工程運行類信息、常量、靜態變量、程序指令、局部變量、操作數棧、方法出入口、動態連接、字面變量、符號引用、對象都存放在哪裏呢?當然是放在內存裏,今天有複習了一遍jvm,下面是我自己看得筆記。
數據庫分爲線程私有和公有。
程序計數器
程序計數器是線程私有的,佔很小內存,用於存放字節碼行號指示器,跳轉、分支、循環、異常處理、程序恢復等,java虛擬機規範中沒有規定任何OutOfMemoryError情況區域。
虛擬機棧
虛擬機棧式線程私有的,進入某個方法的同時會創建一個棧幀,裏面存放着局部變量、操作數棧、動態連接、方法出入口等信息,每個方法從調用到結束就是棧幀的入棧與出棧。
局部變量:byte、short、char、int、long、float、double、boolean、reference、returnAddress類型。
操作數棧:就是用來臨時存放操作數的區域,可見。
動態連接:編譯時能把一些符號引用換成直接引用,java語言具有動態性,有些需要在運行時動態轉換就是動態連接,可見。
此區域會發生兩種內存異常,棧深度不夠StackOverflowError,空間不夠OutOfMemoryError。
本地方法棧
本地方法棧和虛擬機棧十分相似指的是虛擬機使用到的native服務使用的棧幀也會有StackOverflowError和OutOfMemoryError,虛擬機 規範沒有對它使用的語言、數據結構、使用方式做限定取決於具體虛擬機實現。
堆
是線程共享的,用來存放java抽象對象和數組,佔內存最大的一塊,是java垃圾收集管理的主要區域,被稱爲GC堆。不要求是連續的物理空間,只要邏輯連續就行,在實現時可以是固定的和擴展的,一般都是擴展的,通過-Xms和-Xmx控制,當堆空間不足或者達到擴展上線發生OutOfMemoryError。
方法區
是線程共享的,用於存放類信息、常量、靜態變量、即時生成的代碼等信息,回收的主要目標是常量池和類型的卸載,類型卸載要求苛刻,垃圾收集行爲在這發生的比較少,但是必要的,HotSpot虛擬機低版本把這塊歸爲“永久代”導致過內存泄露OutOfMemoryError。
運行時常量池
屬於方法區的一部分,用於存放類加載後的字面變量和符號引用,java虛擬機規範對它沒有做任何細節的約束,翻譯出來的直接引用也可以存放於此。運行時常量池相對於class常量池來說具有動態性,運行時產生的字面變量(String.intern())和符號引用可以動態放於此。
直接內存
直接內存不是java虛擬機運行時數據區的一部分,是native服務直接使用的內存空間,比如NIO使用native函數庫直接分配堆外內存,所以它就不受虛擬機分配內存參數限制,需要在弄閥值時考慮到這部分空間的存在。