1. 程式人生 > >jvm java虛擬機器 新生代的配置

jvm java虛擬機器 新生代的配置

1.1.1.1. -Xmn引數

引數-Xmn1m可以用於設定新生代的大小。設定一個較大的新生代會影響老生代的大小,因為這兩者的總和是一定的,這個系統引數對於系統性能以及GC行為有很大的影響,新生代一般設定為整個堆空間的1/31/4左右最合適。

引數-XX:SurvivorRatio用來設定新生代中eden空間和from/to空間的比例,公式如下:

-XX:SurvivorRatio=eden/from =eden/to

解釋:fromto之間的兩塊區間記憶體是相等的。可以參考

這篇文章,下面的輸出也會印證fromto之間的兩塊區間記憶體是相等的。

使用不同的堆分配引數確實有很大的影響,下面開始驗證影響。

下面程式碼是迴圈十次每次申請1M的空間一共申請10M,程式碼如下:

byte[] b = null;
for (int i = 0; i < 10; i++) {
b = new byte[1 * 1024 * 1024];
}


1.1.1.2. 第一種情況:-Xmx20m -Xms20m -Xmn1m -XX:SurvivorRatio=2 -XX:+PrintGCDetails

配置上面的引數程式的輸出如下:

[GC [DefNew: 512K->256K(768K), 0.0010949 secs] 512K->377K(20224K), 0.0011182 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

Heap

 def new generation  total 768K, used 488K [0x335d0000, 0x336d0000, 0x336d0000)

  eden space 512K, 45% used [0x335d0000, 0x3360a2e0, 0x33650000)

from space 256K,100% used [0x33690000, 0x336d0000, 0x336d0000)

  to   space 256K,  0% used [0x33650000, 0x33650000, 0x33690000)

 tenured generation   total 19456K, used 10361K[0x336d0000, 0x349d0000, 0x349d0000)

   the space 19456K,  53% used [0x336d0000, 0x340ee730, 0x340ee800, 0x349d0000)

 compacting perm gen  total 12288K, used 146K [0x349d0000, 0x355d0000, 0x389d0000)

   the space 12288K,   1% used [0x349d0000, 0x349f4a58, 0x349f4c00, 0x355d0000)

    ro space 10240K,  45% used [0x389d0000, 0x38e59b28, 0x38e59c00, 0x393d0000)

    rw space 12288K,  54% used [0x393d0000, 0x39a5d0e8, 0x39a5d200, 0x39fd0000)

設定的edenfrom的比例是2:1 from=to 這裡前面說過,輸出也確實證明是相等的。所以eden512K,新生代我們分配的是1M=512K+256K+256k=1024K=1M,總的可用的新生代為512K+256K=768K;

由於新生代的eden區域的記憶體為512K我們每次申請的空間是1M,所以沒有辦法容納,因此觸發了一次GC垃圾回收,對eden區域的記憶體進行了部分的回收,新生代沒有記憶體容納1M的記憶體還是不夠儲存,所以陣列都被分配到老生代,老生代最終佔用了10361K空間。

1.1.1.3. 第二種情況:-Xmx20m -Xms20m -Xmn7m -XX:SurvivorRatio=2 -XX:+PrintGCDetails

第二種情況將新生代記憶體擴大到7M,輸出如下:

[GC [DefNew: 2795K->1498K(5376K), 0.0018315 secs] 2795K->1498K(18688K), 0.0018637 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

[GC [DefNew: 4687K->1024K(5376K), 0.0011140 secs] 4687K->1498K(18688K), 0.0011327 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

[GC [DefNew: 4125K->1024K(5376K), 0.0004712 secs] 4599K->1498K(18688K), 0.0004903 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

Heap

 def new generation   total 5376K, used 3163K [0x335d0000, 0x33cd0000, 0x33cd0000)

  eden space 3584K, 59% used [0x335d0000, 0x337e6d38, 0x33950000)

  from space 1792K, 57% used [0x33b10000, 0x33c10010, 0x33cd0000)

  to   space 1792K,  0% used [0x33950000, 0x33950000, 0x33b10000)

 tenured generation   total 13312K, used 474K[0x33cd0000, 0x349d0000, 0x349d0000)

   the space 13312K,   3% used [0x33cd0000, 0x33d468e0, 0x33d46a00, 0x349d0000)

 compacting perm gen  total 12288K, used 146K [0x349d0000, 0x355d0000, 0x389d0000)

   the space 12288K,   1% used [0x349d0000, 0x349f4a58, 0x349f4c00, 0x355d0000)

    ro space 10240K,  45% used [0x389d0000, 0x38e59b28, 0x38e59c00, 0x393d0000)

    rw space 12288K,  54% used [0x393d0000, 0x39a5d0e8, 0x39a5d200, 0x39fd0000)

在這個引數下eden的記憶體為3584K所以可以有空間儲存陣列,所以陣列先被分配到這個eden區,但是還不能完全預留全部的10M記憶體,所以執行的時候產生了3GC垃圾回收,因為程式申請記憶體的時候,變數失去了上一次的引用指標。所以是在新生代中進行GC垃圾回收。最終的結果:所有的記憶體都被分配到新生代進行,通過GC保證了新生代有足夠的空間儲存。而沒有進入老年代,只是在GC過程中,部分新生物件晉升到老年代。

1.1.1.4. 第三種情況:-Xmx20m -Xms20m -Xmn15m -XX:SurvivorRatio=8 -XX:+PrintGCDetails

第三種情況將新生代記憶體擴大到15M,輸出如下:

Heap

 def new generation   total 13824K, used 11223K [0x335d0000, 0x344d0000, 0x344d0000)

  eden space 12288K,  91% used [0x335d0000, 0x340c5f50, 0x341d0000)

  from space 1536K,  0% used [0x341d0000, 0x341d0000, 0x34350000)

  to   space 1536K,  0% used [0x34350000, 0x34350000, 0x344d0000)

 tenured generation   total 5120K, used 0K[0x344d0000, 0x349d0000, 0x349d0000)

   the space 5120K,   0% used [0x344d0000, 0x344d0000, 0x344d0200, 0x349d0000)

 compacting perm gen  total 12288K, used 146K [0x349d0000, 0x355d0000, 0x389d0000)

   the space 12288K,   1% used [0x349d0000, 0x349f4a58, 0x349f4c00, 0x355d0000)

    ro space 10240K,  45% used [0x389d0000, 0x38e59b28, 0x38e59c00, 0x393d0000)

    rw space 12288K,  54% used [0x393d0000, 0x39a5d0e8, 0x39a5d200, 0x39fd0000)

在這次的測試中,新生代被分配15M記憶體,eden的記憶體是12288K所有這個區域完全可以容納10M的記憶體陣列,所以所有的分配都是在eden直接進行,並沒有觸發GC垃圾回收,因此from/to和老年代tenured使用率都是0.

通過上面的例子,發現不同的堆分配策略對系統執行的影響還是很大。所以在實際開發中,還是要合理的設定值,基本策略:儘可能將物件預留在新生代,減少老年代GC次數。(第一種情況物件都被分配到老年代,老年代肯定要進行GC垃圾回收)

1.1.1.5. -XX:NewRatio引數

-XX:NewRatio引數主要設定新生代和老年代的比例。公式如下:

-XX:NewRatio=老年代/新生代

1.1.1.6. 第四種情況:-Xmx20m -Xms20m  -XX:NewRatio=2 -XX:+PrintGCDetails

第四種引數設定為:-Xmx20m -Xms20m  -XX:NewRatio=2 -XX:+PrintGCDetails 程式的輸出如下:

[GC [DefNew: 4899K->474K(6144K), 0.0016090 secs] 4899K->1498K(19840K), 0.0016426 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

[GC [DefNew: 5768K->0K(6144K), 0.0011308 secs] 6792K->2522K(19840K), 0.0011490 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

Heap

 def new generation   total 6144K, used 1134K [0x335d0000, 0x33c70000, 0x33c70000)

  eden space 5504K,  20% used [0x335d0000, 0x336eb8c8, 0x33b30000)

  from space 640K,   0% used [0x33b30000, 0x33b30088, 0x33bd0000)

  to   space 640K,   0% used [0x33bd0000, 0x33bd0000, 0x33c70000)

 tenured generation   total 13696K, used 2522K [0x33c70000, 0x349d0000, 0x349d0000)

   the space 13696K,  18% used [0x33c70000, 0x33ee6878, 0x33ee6a00, 0x349d0000)

 compacting perm gen  total 12288K, used 146K [0x349d0000, 0x355d0000, 0x389d0000)

   the space 12288K,   1% used [0x349d0000, 0x349f4a58, 0x349f4c00, 0x355d0000)

    ro space 10240K,  45% used [0x389d0000, 0x38e59b28, 0x38e59c00, 0x393d0000)

    rw space 12288K,  54% used [0x393d0000, 0x39a5d0e8, 0x39a5d200, 0x39fd0000)

因為堆空間分配的記憶體為20M,老年代和新生代比例我們設定的是2:1,所以新生代的記憶體大約是6144K 老年代的記憶體是13696K由於新生代Gc的時候,from/to的記憶體容納不下任何一個1m陣列物件,影響了新生代的正常回收,所以物件都跑到老年代空間了。因此導致兩個1MB陣列進入老年代,(新生代GC,還有1M陣列倖存,按理說應進入from/to但是from/to只有640K空間不足)

注意:

-XX:SurvivorRatio可以設定eden區與Survivor區比例,-XX:NewRatio可以設定老年代新生代的比例。

完成的公式如下圖所示:


相關推薦

jvm java虛擬機器 新生代配置

1.1.1.1. -Xmn引數 引數-Xmn1m可以用於設定新生代的大小。設定一個較大的新生代會影響老生代的大小,因為這兩者的總和是一定的,這個系統引數對於系統性能以及GC行為有很大的影響,新生代一般

jvm java虛擬新生代配置

方法區 tools images 轉載 影響 tool 引用 blog avi 版權聲明:本文為博主原創文章,未經博主允許不得轉載。不經過允許copy,講追究法律責任,歡迎加入我們的學習提升群523988350,可以相互交流 目錄(?)[+] 111 -Xmn參數

java虛擬機器JVM--java虛擬機器的記憶體管理(新生代、老年代)

前言 在上一篇部落格中,還遺留了一個問題:JVM的記憶體如何分配最高效?換一種說法就是:JVM的記憶體是如何的分配以及回收的?通過前面兩篇部落格的鋪墊:java虛擬機器JVM–java虛擬機器的結構, java虛擬機器JVM–java虛擬機器垃圾的回收機制詳解

JVM - Java 虛擬機器的記憶體劃分

本文章內容來自《深入理解jvm虛擬機器》一書,有興趣的同學可以看下這本書。 Java虛擬機器在執行Java程式的過程中會將自身所管理的記憶體劃分為若干個不同的資料區。這些區域都有各自的用途,以及建立和銷燬的時間。 記憶體模組大致如下(該圖依據《深入理解Java虛擬機器一書》) 列個

深入JVM(Java虛擬機器)(一)Java虛擬機器記憶體區域劃分

   本文為博主參閱自《深入理解Java虛擬機器:JVM高階特性與最佳實踐(第2版)》,書中的全部講解均以《Java虛擬機器規範(Java SE 7)》為依據    圖一中為JVM規範中對java虛擬機器記憶體區域的劃分及定義,為單執行緒時的粗略劃分 圖二,中所繪為JVM

(jvm-java虛擬機器)棧,堆,方法區的關係

                 很多人雖然會些一些程式碼,但是並不知道這些資料,程式碼適怎樣執行實現的,那我們就要來看看jvm(也就是java虛擬機器)。                  java虛擬機器其實就是java程式執行的一個載體,java程式啟動時,java

JVM——Java虛擬機器架構

0. 前言Java虛擬機器(Java virtualmachine)實現了Java語言最重要的特徵:即平臺無關性。平臺無關性原理:編譯後的 Java程式(.class檔案)由 JVM執行。JVM遮蔽了與

深入理解JVM——Java虛擬機器記憶體模型

開發十年,就只剩下這套架構體系了! >>>   

深入理解java虛擬機器JVM調優配置

轉載文章:http://blog.csdn.net/sivyer123/article/details/17139443 堆記憶體設定 原理 JVM堆記憶體分為2塊:Permanent Space 和 Heap Space。 Permanent 即 持久代(Pe

Java虛擬機器JVM)引數配置說明

如果你要在J2EE環境中配置這些引數,那麼你需要在J2EE應用伺服器或者Servlet容器相關啟動引數設定處指定,其啟動檔案中來配置,Tomcat是在catalina.bat中配置,weblogic和websphere是在其他地方,具體我就說了,相信玩過的這些大型伺服器的人都知道,沒玩過的看看這篇文章,玩玩

Java虛擬機器詳解03----常用JVM配置引數

本文主要內容: Trace跟蹤引數 堆的分配引數 棧的分配引數 零、在IDE的後臺列印GC日誌: 既然學習JVM,閱讀GC日誌是處理Java虛擬機器記憶體問題的基礎技能,它只是一些人為確定的規則,沒有太多技術含量。 既然如此,那麼在I

Java虛擬機器探究】5.常用JVM配置引數-棧的分配引數

在使用JVM編譯java時,都會去設定相關的引數(例如使用eclipse的時候,可以設定eclipse的eclipse.ini檔案來對jvm做一些引數配置)。jvm的引數設定主要涉及到三種,分別是Trace跟蹤引數、堆的分配引數、棧的分配引數。本章主要講解棧的分配引數的相關資

Java虛擬機器-JVM各種引數配置大全詳細

 usr/local/jdk/bin/java -Dresin.home=/usr/local/resin -server -Xms1800M -Xmx1800M -Xmn300M -Xss512K -XX:PermSize=300M -XX:MaxPermSize=3

Java虛擬機器詳解----常用JVM配置引數

原文地址:http://www.cnblogs.com/smyhvae/p/4736162.html 本文主要內容: Trace跟蹤引數堆的分配引數棧的分配引數 零、在IDE的後臺列印GC日誌: 既然學習JVM,閱讀GC日誌是處理Java虛擬機器記憶體問題的

學習筆記1:深入理解Java虛擬機器——JVM高階特性與最佳實踐_OOM(記憶體溢位)_虛擬機器引數設定_MAT

eclipse中設定debug標籤頁的vm引數 1,Run->Debug configurations->Java Application 2,選中已經寫好的專案 3,Arguments->VM arguments 4,在VM arguments 裡面就可以對虛擬機器的

學習筆記1:深入理解Java虛擬機器——JVM高階特性與最佳實踐_走進java_java記憶體區域與記憶體溢位異常

第一部分:走進java Java虛擬機器 程式碼在華章下載 jdk釋出了六個命令列工具和兩個視覺化故障處理工具。 推薦書籍 設計原本 領域特定語言 現在著名的Java虛擬機器 hotspot vm(預設) jrockit vm j9 vm jdk sun jdk op

JVM系列第2講:Java 虛擬機器的歷史

說起 Java 虛擬機器,許多人就會將其與 HotSpot 虛擬機器等同看待。但實際上 Java 虛擬機器除了 HotSpot 之外,還有 Sun Classic VM、Exact VM、BEA JRocketit、IBM J9 等等。今天我們就來簡單回顧下 Java 虛擬機器的發展歷史。 虛擬機器始祖:S

Java虛擬機器(Jvm原始碼):Mac安裝JProfiler和IDE整合

首先介紹一下JProfiler JProfiler是一個專業工具,用於分析正在執行的JVM中發生的事情。當您的生產系統遇到問題時,您可以將其用於開發,質量保證和消防任務。 當然這個軟體是需要收費的,這個需要你自行衡量下。 我的建議是有能力,財力雄厚就買正版,或者使用其他免費的Ja

Java虛擬機器JVM原始碼):JDK10對Java虛擬機器執行時資料區的劃分(詳細圖解)

Java虛擬機器執行時資料區 為什麼要研究這個,因為JDK都已經發布到10了,必須要更新自己對Java虛擬機器新的認識。 一、執行時資料區的劃分 1.1 官方劃分 關於JDK10對執行時資料區的劃分,在官方文件說的非常清楚。 學習技術,一定要學會看第一手資料。 Ja

Java虛擬機器JVM原始碼):搭建OpenJDK(10)原始碼除錯環境

為什麼要自己除錯 在前面的文章,已經介紹了如何編譯自己的OpenJDK。 但是光擁有了自己的JDK版本肯定是不夠的。 為了深入瞭解Java例項的建立、初始化和執行流程以及內部實現原理,DEBUG是必不可少的必殺技。 所以,作為搞技術的有必要學習如何除錯JVM原始碼。