1. 程式人生 > >JVM參數調優

JVM參數調優

垃圾回收 time 收集 回收 需要 初始 jvm參數 出現 大內存

JVM參數配置

JVM提供了諸多的參數進行JVM各個方面內存大小的設置,為Java應用進行優化提供了諸多的工具,本文將會詳細分析各個參數的功能與使用。

常見參數配置

-XX:+PrintGC 每次觸發GC的時候打印相關日誌

-XX:+UseSerialGC 串行回收

-XX:+PrintGCDetails 更詳細的GC日誌

-Xms 堆初始值

-Xmx 堆最大可用值

-Xmn 新生代堆最大可用值

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

-XX:NewRatio 配置新生代與老年代占比 1:2

含以-XX:SurvivorRatio=eden/from=den/to

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

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

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

初始隊內存 與 電腦內存有關 默認4G

新生代最大可用值 滿了發生Minor GC

Full GC 新生代 老年代 都會一起回收了

堆的初始值和最大值一定要相等,不相等的情況下 垃圾回收不停的回收 不停的申請 不停的回收

1、垃圾回收時候 其他線程要停止 停頓一下 如果堆內存和最大不同 不停回收 那麽程序斷斷續續的進行 非常不好 大家要註意

如果不暫停 再次期間產生的新的垃圾不能回收

2、 新生代小於老年代 新生代回收的頻率高 老年代低 讓新生代去頻繁收集 所以調小一些 新生代:老年代=1:2 新生代占比越小越頻繁 老年代打不頻繁

廢話不多說!實踐!

實戰一、堆內存大小配置

package jvmTest;

//打印堆的基本內存信息
public class Test02 {
  public static void main(String[] args) {
        System.out.print("最大內存");
        System.out.println(Runtime.getRuntime().maxMemory() 
/ 1024.0 / 1024 + "M"); System.out.print("可用內存"); System.out.println(Runtime.getRuntime().freeMemory() / 1024.0 / 1024 + "M"); System.out.print("已經使用內存"); System.out.println(Runtime.getRuntime().totalMemory() / 1024.0 / 1024 + "M"); } }

技術分享圖片

這是默認的堆存的狀態

進行設置: -Xmx20m -Xms5m 初始5m 最大20m

技術分享圖片

運行結果:

技術分享圖片

已使用內存 根據初始值申請來的 !

來4M的內存看看:

package jvmTest;

//打印堆的基本內存信息
public class Test02 {
  public static void main(String[] args) {
        byte[] b = new byte[4 * 1024 * 1024];  //4M
        System.out.print("最大內存");
        System.out.println(Runtime.getRuntime().maxMemory() / 1024.0 / 1024 + "M");
        System.out.print("可用內存");
        System.out.println(Runtime.getRuntime().freeMemory() / 1024.0 / 1024 + "M");
        System.out.print("已經使用內存");
        System.out.println(Runtime.getRuntime().totalMemory() / 1024.0 / 1024 + "M");
}
        
}

運行結果:

技術分享圖片

使用內存 > 9M

但是不能申請25M給它哦,會堆溢出的~大家可以試試

設置新生代比例參數

使用示例: -Xms20m -Xmx20m -Xmn1m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC

說明:堆內存初始化值20m,堆內存最大值20m,新生代最大值可用1m,eden空間和from/to空間的比例為2/1 (2:1:1)

Eden 默認 比S0、S0要打 因為S0、S1要復制的 不要太大了

package jvmTest;

//打印堆的基本內存信息
public class Test02 {
  public static void main(String[] args) {
      System.out.println("ssssss");
      byte[] b = null;
      for (int i = 0; i < 10; i++) {
      b = new byte[1 * 1024 * 1024];
      }

 }
  }    

結果:

技術分享圖片

出現框框內的 說明內存不夠 進行垃圾回收了

下面的分配:

技術分享圖片

配置新生代的

eden空間和from/to空間的比例為2/1 2:1:1 結果展示完美~~

下面這麽配置一下看看:

-XX:+PrintGCDetails -XX:+UseSerialGC

技術分享圖片

結果沒有回收哦

最大始值設置20M時候會有 GC回收日誌

因為之前這段代碼運行時候 需要的內存是 10M i=10嘛 但是這時候新生代最大可用值是1M 這時候空間不夠 為了夠用 不停的回收 內存不夠了就會不停的回收

設置新生代與老年代比例參數

使用示例: -Xms20m -Xmx20m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC -XX:NewRatio=2

說明:堆內存初始化值20m,堆內存最大值20m,新生代最大值可用1m,eden空間和from/to空間的比例為2/1

新生代和老年代的占比為1/2

哇,竟然回收了三次!

技術分享圖片

新生代與老年的的占比是 1:2 看到eden+from+to : 1369 大致是哦

當然我們可以看下默認占比

技術分享圖片

大致為:13696:6784=1:2

JVM參數調優