1. 程式人生 > >JVM虛擬機器概念瞭解

JVM虛擬機器概念瞭解

  1. 虛擬機器就是一臺虛擬的機器,可以分為系統虛擬機器和程式虛擬機器兩種,系統虛擬機器是一個完成的作業系統的軟體平臺; 程式虛擬機器就是為 執行單個計算機程式而設計的,比較著名的就是java虛擬機器。 常用的系統虛擬機器 :visual Box、vmware; 常用的 java程式虛擬機器: classic、hotsport等

  2. java虛擬機器基本概念瞭解
    在這裡插入圖片描述

  • 類載入器:

負責從檔案系統中或者網路中載入類和介面資訊並賦予唯一的名字,載入的c資訊都放到了方法區的空間,

  • Java堆

在java虛擬機器啟動時建立java堆,幾乎所有物件例項都放在java堆中,它是執行緒共享的,Heap中的物件的記憶體需要等待GC進行回收。

  • Java虛擬機器棧

執行緒私有記憶體空間,有區域性變數、運算元幀和幀資料區
區域性變數:報錯函式的引數區域性變數
運算元幀:儲存中間結果
幀資料區:返回結果異常,異常處理表,方便異常時找到異常程式碼
每個方法在執行時都會建立一個棧幀用於儲存區域性變量表、運算元幀、動態連結、方法出口等資訊。每個方法從呼叫直至到執行完成的過程,就對應著一個棧幀在虛擬機器棧中入棧到出棧的過程。如果請求的棧的深度大於虛擬機器所允許的深度就會丟擲stackOverflowError異常(遞迴呼叫,遞迴不是馬上返回而是一層層儲存,滿足新增後才一層層返回),虛擬機器棧在動態擴充套件無法申請到足夠的記憶體就會報outOfMemoryError異常

  • 方法區

存放類資訊、類的方法、常量資訊、常量池資訊還有字串和數字常量,在一定的條件下它也會被GC,當方法區域需要使用的記憶體超過其允許的大小時,會丟擲OutOfMemory的錯誤資訊。方法區理解為永久區時執行緒共享的區域。

  • 本地方法棧

依賴於本地方法的實現,如某個JVM實現的本地方法藉口使用C連線模型,則本地方法棧就是C棧,可以說某執行緒在呼叫本地方法時,就進入了一個不受JVM限制的領域,也就是JVM可以利用本地方法來動態擴充套件本身。

  • pc暫存器
    每一個執行緒都有它自己的PC暫存器,也是該執行緒啟動時建立的。PC暫存器的內容總是指向下一條將被執行指令的餓地址,這裡的地址可以是一個本地指標,也可以是在方法區中相對應於該方法起始指令的偏移量。
    若thread執行Java方法,則PC儲存下一條執行指令的地址。若thread執行native方法,則Pc的值為undefined
  • 回收系統

通常我們說的JVM記憶體回收總是在指堆記憶體回收,確實只有堆中的內容是動態申請分配的,所以以上物件的年輕代和年老代都是指的JVM的Heap空間,而持久代則是之前提到的MethodArea,不屬於Heap。
GC的基本原理:將記憶體中不再被使用的物件進行回收,GC中用於回收的方法稱為收集器,由於GC需要消耗一些資源和時間,Java在對物件的生命週期特徵進行分析後,按照新生代、舊生代的方式來對物件進行收集,以儘可能的縮短GC對應用造成的暫停

  • 執行引擎

虛擬機器的核心就是執行引擎,它負責處理虛擬機器的位元組碼檔案,一般是先編譯成機器碼在執行

  • 直接記憶體

java的NIO庫允許java使用直接記憶體從而提高效能,速度優於java堆。

  1. 記憶體溢位的原理以及處理:OutOfMemoryError
  • OutOfMemoryError: PermGen space(方法區)

【原因】發生這種問題的原意是程式中使用了大量的jar或class,使java虛擬機器裝載類的空間不夠,與Permanent Generation space有關。
【解決】解決辦法 :增加java虛擬機器中的XX:PermSize和XX:MaxPermSize引數的大小,其中XX:PermSize是初始永久儲存區域大 小,XX:MaxPermSize是最大永久儲存區域大小。如針對tomcat6.0,在catalina.sh 或catalina.bat檔案中一系列環境變數名說明結束處(大約在70行左右) 增加一行: JAVA_OPTS=" -XX:PermSize=64M -XX:MaxPermSize=128m"

  • OutOfMemoryError:Java heap space(堆記憶體)

【原因】發生這種問題的原因是java虛擬機器建立的物件太多,在進行垃圾回收之間,虛擬機器分配的到堆記憶體空間已經用滿了,與Heap space有關。
【解決】解決辦法:增加Java虛擬機器中Xms(初始堆大小)和Xmx(最大堆大小)引數的大小。如:set JAVA_OPTS= -Xms256m -Xmx1024m

  • -OutOfMemoryError:unable to create new native thread(Java棧)

【原因】Stack空間不足以建立額外的執行緒,要麼是建立的執行緒過多,要麼是Stack空間確實小了。
【解決】解決辦法: 我們可以通過調整jvm引數,降低為每個執行緒分配的棧記憶體大小來解決問題,例如在jvm引數中新增-Xss128k將執行緒棧記憶體大小設定為128k。

  • java.lang.StackOverflowError

【原因】:這也記憶體溢位錯誤的一種,即執行緒棧的溢位,要麼是方法呼叫層次過多(比如存在無限遞迴呼叫),要麼是執行緒棧太小。
【解決】:優化程式設計,減少方法呼叫層次;調整-Xss引數增加執行緒棧大小。