7、jvm基本結構 優化配置

1.2認識java虛擬機的基本結構

  

1.3基本概念說明

1、類加載子系統:負責從文件系統或者網絡中加載Class信息,加載的信息存放在一塊稱之爲方法區的內存空間。

  

2、方法區:就是存放類信息、常量信息、常量池信息、包括字符串字面量和數字常量等。

  

3、java堆:在java虛擬機啓動的時候建立java堆,它是java程序最主要的內存工作區域,幾乎所有的對象實例都存放到java堆中,堆空間是所有線程共享的。

  

4、直接內存:Java的NIO庫允許java程序使用直接內存,從而提高性能,通常直接內存速度會優於Java堆。讀寫頻繁的場合可能會考慮使用。

  

5、每個虛擬機線程都有一個私有的棧,一個線程的java棧在線程創建的時候被創建,java棧中保留着局部變量、方法參數、同時java的方法調用、返回值等。

  

6、本地方法棧和Java棧非常類似,最大不同爲本地方法棧用於本地方法調用。java虛擬機允許java直接調用本地方法(通常使用C編寫)。

  

7、垃圾收集系統是java的核心,也是必不可少的,java有一套自己進行垃圾清理的機制,默認採用的是複製算法。開發人員無需手工清理,我們稍後詳細說明。

  

8、PC(ProgramCounter)寄存器也是每個線程私有的空間,java虛擬機會爲每個線程創建PC寄存器,在任意時刻,一個Java線程總是在執行一個方法,這個方法被稱爲當前方法,如果當前方法不是本地方法,PC寄存器就會執行當前正在被執行的指令,如果是本地方法,則PC寄存器值爲undefined,寄存器存放如當前執行環境指針、程序計數器、操作棧指針、計算的變量指針等信息。

  

9、虛擬機最核心的組件就是執行引擎了,它負責執行虛擬機的字節碼。一般會先進行編譯成機器碼後執行

  

  

2.1堆、棧、方法區概念和聯繫

堆解決的是數據存儲的問題,即數據怎麼放、放在哪。

棧解決程序的運行問題,即程序如何執行,或者說如何處理數據。

方法區則是輔助堆棧的一塊永久區(Perm),解決堆棧信息的產生,是先決條件。

我們創建一個新的對象,User:那麼User類的一些信息(類信息、靜態信息都存在於

方法區中)

而user類被實例化出來之後,被存儲到ava堆中。一塊內存空間

當我們去使用的時候,都是使用User對象的引用,形如User user=new User();

這裏的user就是存放在java棧中的,即User真實對象的一個引用。

  

  

2.2 辨清java堆

java堆是和java應用程序關係最密切的內存空間,幾乎所有的對象都存放在其中,並且]ava堆完全是自動化管理的,通過垃圾回收機制,垃圾對象會自動清理,不需要顯示地釋放。

根據垃圾回收機制不同,Java堆有可能擁有不同的結構。最爲常見的就是將整個java堆分爲新生代和老年代。其中新生代存放新生的對象或者年齡不大的對象,老年代則存放老年對象。

新生代分爲eden區、s0區、s1區,s0和s1也被稱爲from和to區域,他們是兩塊大小相等並且可以互換角色的空間·

絕大多數情況下,對象首先分配在eden區,在一次新生代回收後,如果對象還存活,則會進入s0或者s1區,之後每經過一次新生代回收,如果對象存活則它的年齡就加1,當對象達到一定的年後,則進入老年代。

  

2.3java棧

java棧是一塊線程私有的內存空間,一個棧,一般由三部分組成:局部變量表、操作數棧和幀數據區。

局部變量表:用於報錯函數的參數及局部變量。

操作數棧:主要保存計算過程的中間結果,同時作爲計算過程中變量臨時的存儲空間。

幀數據區:除了局部變量表和操作數棧以外,棧還需要一些數據來支持常量池的解析,這裏幀數據區保存着訪問常量池的指針,方便程序訪問常量池,另外,當函數返回或者出現異常時,虛擬機必須有一個異常處理表,方便發送異常的時候找到異常的代碼,因此異常處理表也是幀數據區的一部分。

  

  

2.4java方法區

java方法區和堆一樣,方法區是一塊所有線程共享的內存區域,它保存系統的類信息,比如類的字段、方法、常量池等。方法區的大小決定了系統可以保存多少個類,如果系統定義太多的類,導致方法區溢出。虛擬機同樣會拋出內存溢出錯誤。方法區可以理解爲永久區(Perm)。

  

  

3.2堆分配參數

-XX:+PrintGC 使用這個參數,虛擬機啓動後,只要遇到GC就會打印日誌。

-XX:+UseSeriaIGC 配置串行回收器

-XX:+PrintGCDetails 可以查看詳細信息,包括各個區的情況

-Xms: 設置java程序啓動時初始堆大小

-Xmx: 設置java程序能獲得的最大堆大小

-Xmx20m -Xms5m -XX:+PrintCommandLineFlags:可以將隱式或者顯示傳給虛擬機的參數輸出

總結: 在實際工作中,我們可以直接將初始的堆大小與最大堆大小設置相等,

這樣的好處是可以減少程序運行時的垃圾回收次數,從而提高性能。

  

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

  

新生代的配置

-Xmn: 可以設置新生代的大小,設置一個比較大的新生代會減少老年代的大小,這個參數對系統性能以及GC行爲有很大的影響,新生代大小一般會設置整個堆空間的1/3到1/4左右。

-XX:SurvivorRatio:用來設置新生代中eden空間和from/to空間的比例。

含義:-XX:SurvivorRatio=edeq/from=eden/to

 

總結:不同的堆分佈情況,對系統執行會產生一定的影響,在實際工作中,應該根據系統的特點做出合理的配置,基本策略:儘可能將對象預留在新生代,減少老年代的GC次數。

除了可以設置新生代的絕對大小(-Xmn),還可以使用(-XX:NewRatio)

設置新生代和老年代的比例:-XX:NewRatio=老年代/新生代

  

3.3棧配置

Java虛擬機提供了參數 -Xss 來指定線程的最大棧空間,整個參數也直接決定了函數可調用的最大深度。

死循環或者遞歸可能會有這個問題:java.lang.StackOverflowError

  

3.4方法區

和java堆一樣,方法區是一塊所有線程共享的內存區域,它用於保存系統的

類信息,方法區(永久區)可以保存信息的多少 可以對其進行配置,在默認情況下,-XX:MaxPermSlze爲64MB,如果系統運行時生產大量的類,就需要設置一個相對合適的方法區,以免出現永久區內存溢出的問題。

-XX:PermSize=64M -XX:MaxPermSize=64M

  

3.5 直接內存配置

直接內存也是java程序中非常重要的組成部分,特別是廣泛用在NIO中,直接內存跳過了Java堆,使Java程序可以直接訪問原生堆空間,因此在一定程度上加快了內存空間的訪問速度。但是說直接內存一定就可以提高內存訪問速度也不見得,具體情況具體分析。

相關配置參數:-XX:MaxDirectMemorySize,如果不設置,默認值爲最大堆空間,即-Xmx 直接內存使用達到上限時,就會觸發垃圾回收,如果不能有效的釋放空間,也會引起系統的00M.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章