歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Java內存區域與內存溢出異常

運行時數據區域

程序計數器(Program Counter Register):可看作是當前程序所執行的字節碼的行號指示器。在虛擬機的概念模型裡(不同虛擬機可能有不同的實現方法),字節碼解釋器就是通過改變程序計數器的值來取下一條字節碼指令,分支、循環、跳轉、異常處理、線程恢復等基礎功能都依賴於這個計數器。

Java虛擬機棧(Java Virtual Machine Stacks):與程序計數器一樣,Java虛擬機棧也是線程私有的,他的它的生命周期和線程相同,虛擬機棧描述的是Java方法執行的內存模型:每個方法在執行的同時都會創建一個棧幀(Stack Frame)用於存儲局部變量表、操作數棧、動態鏈接、方法出口等信息。每一個方法從調用到執行完成的過程,就對應著一個棧幀在虛擬機棧中從入棧到出棧的過程。

有人把Java內存分為堆(Heap)內存和棧(Stack)內存,而“棧”就是現在講的虛擬機棧。局部變量表存放了相關局部變量,包括基本數據類型、對象引用和返回地址等。

虛擬機棧包括兩種異常,StackOverflowError:所請求的棧深度大於虛擬機棧允許的最大深度。OutOfMemoryError:虛擬機棧擴展時無法申請到足夠內存。

本地方法棧(Native Method Stacks):本地方法棧與虛擬機棧十分類似,不同之處在於虛擬機棧為虛擬機執行Java方法服務,而本地方法棧為虛擬機執行Native method服務,在有的虛擬機中直接將本地方法棧和虛擬機棧合二為一了。

Java堆(Heap):虛擬機管理內存中最大的一塊,很多時候也被稱為GC堆,Java堆被所有線程所共享,它在虛擬機啟動時創建,用於存放對象實例。從內存回收角度看,該區又可細分為Eden空間、From Survivor空間和To Survivor空間,從內存分配角度看,該區可能劃分出多個線程私有的分配緩沖區(Thread Local Allocation Buffer,TLAB)。Java堆可以處於物理上不連續的內存空間中(邏輯上連續即可),目前主流的虛擬機的堆都是可擴展的(-Xms、-Xmx),若堆中內存不足以完成實例分配,也無法再擴展時,會拋出OutOfMemoryError異常。

方法區(Method Area):方法區也是各個線程所共享的內存區域,它用於存儲已被虛擬機加載的類信息、常量、靜態變量、編譯器即時編譯的代碼等數據。方法區的內存回收目標主要針對常量池的回收和對類型的卸載,當方法區無法滿足內存分配需求時,會拋出OutOfMemoryError異常。

運行時常量池(Runtime Constant Pool):運行時常量池是方法區的一部分,常量池(Constant Pool Table)用於存放編譯期生成的各種字面量和符號引用,在類加載後進入方法區的運行時常量池中存放。

直接內存(Direct Memory):直接內存不是Java虛擬機定義的內存區域,在JDK1.4中新加入了NIO(New Input/Output)類,引入了一種基於通道與緩沖區的IO方式,它可以使用Native函數庫直接分配堆外內存,然後通過存儲在Java堆中的DirectByBuffer對象引用這塊內存,直接內存不受Java堆大小限制,只受本機總內存和處理器尋址空間的限制

參考資料:《深入理解Java虛擬機 JVM高級特性與最佳實踐》

深入理解Java虛擬機:JVM高級特性與最佳實踐 第2版 高清PDF+源碼 下載 http://www.linuxidc.com/Linux/2014-09/106869.htm

Copyright © Linux教程網 All Rights Reserved