1. 程式人生 > >JVM虛擬機(三):參數配置

JVM虛擬機(三):參數配置

jvm memory 方法 ota owa int 空間不足 private clip

在虛擬機運行的過程中,如果可以跟蹤系統的運行狀態,那麽對於問題的故障排查會有一定的幫助,為此,虛擬機提供了一些跟蹤系統狀態的參數,使用給頂的參數執行java虛擬機,就可以在系統運行時打印相關日誌,用於分析實際問題。我們進行迅疾參數配置,其實主要是圍繞著堆、棧、方法區進行配置。

堆分配參數

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

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

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

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

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

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

package com.base001;
 
 
public class Test01 {
 
    public static void main(String[] args) {
 
        //-Xms5m -Xmx20m -XX:+PrintGCDetails -XX:+UseSerialGC -XX:+PrintCommandLineFlags
        
        //查看GC信息
        System.out.println("max memory:" + Runtime.getRuntime().maxMemory());
        System.out.println(
"free memory:" + Runtime.getRuntime().freeMemory()); System.out.println("total memory:" + Runtime.getRuntime().totalMemory()); byte[] b1 = new byte[1*1024*1024]; System.out.println("分配了1M"); System.out.println("max memory:" + Runtime.getRuntime().maxMemory()); System.out.println(
"free memory:" + Runtime.getRuntime().freeMemory()); System.out.println("total memory:" + Runtime.getRuntime().totalMemory()); byte[] b2 = new byte[4*1024*1024]; System.out.println("分配了4M"); System.out.println("max memory:" + Runtime.getRuntime().maxMemory()); System.out.println("free memory:" + Runtime.getRuntime().freeMemory()); System.out.println("total memory:" + Runtime.getRuntime().totalMemory()); } }

點擊右鍵Run As,再點擊Run configurations找到Arguments

技術分享圖片

這是給主函數傳遞一些參數,我們需要的是第二個VM arguments

往裏面添加以下參數

-Xms5m  -Xmx20m -XX:+PrintGCDetails -XX:+UseSerialGC 

分配5m的初始化大小 最大的大小為20m 打印GC詳細信息 使用串行的垃圾回收器

運行代碼控制臺出現:

技術分享圖片
總結:在實際工作中,我們可以直接將初始的堆大小與最大堆大小設置相等,這樣的好處是可以減少程序運行時的垃圾回收次數,從而提高性能。實際工作中一般這些參數都是配置到web容器或者tomcat中的。

註意:-XX開頭的一般都是設置jvm的參數,其它開頭的都是設置具體工程的參數。

堆裏新生代的分配

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

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

package com.base001;
 
public class Test02 {
 
    public static void main(String[] args) {
        
        //第一次配置
        //-Xms20m -Xmx20m -Xmn1m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC
        
        //第二次配置
        //-Xms20m -Xmx20m -Xmn7m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC
        
        //第三次配置
        //-XX:NewRatio=老年代/新生代
        //-Xms20m -Xmx20m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC
        
        byte[] b = null;
        //連續向系統申請10MB空間
        for(int i = 0 ; i <10; i ++){
            b = new byte[1*1024*1024];
        }
    }
}

第一次配置

技術分享圖片

第二次配置

技術分享圖片

第三次配置

技術分享圖片

新生代和老年代的比例是1/2,新生代占一份,老生代占2份。

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

除了可以設置新生代的絕對大小(-Xmn),還可以使用(-XX:NewRatio)設置新生代和老年代的比例:-XX:NewRatio=老年代/新生代

堆溢出處理

在java程序的運行過程中,如果堆空間不足,則會拋出內存溢出的錯誤(Out Of Menory)OOM,一旦這類問題發生在生產環境,可能引起嚴重的業務中斷,java虛擬機提供了-XX:+HeapDumpOnOutOfMemoryError,使用該參數可以在內存溢出是導出整個堆信息,與之配合使用的還有參數,-XX:HeapDumpPath,可以設置到處堆得存放路徑。

內存分析工具:Memory Analyzer 1.5.0

地址:http://download.eclipse.org/mat/1.5/update-site/

package com.base001;
 
import java.util.Vector;
 
public class Test03 {
 
    public static void main(String[] args) {
        
        //-Xms2m -Xmx1m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d:/Test03.dump
        //堆內存溢出
        Vector v = new Vector();
        for(int i=0; i < 5; i ++){
            v.add(new Byte[1*1024*1024]);
        }
        
    }
}

添加參數

技術分享圖片

運行後的結果

技術分享圖片

存放到D盤下的異常文件。

棧配置

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

package com.base001;
 
public class Test04 {
 
    //-Xss1m  
    //-Xss5m
    
    //棧調用深度
    private static int count;
    
    public static void recursion(){
        count++;
        recursion();
    }
    public static void main(String[] args){
        try {
            recursion();
        } catch (Throwable t) {
            System.out.println("調用最大深入:" + count);
            t.printStackTrace();
        }
    }
}

添加參數

技術分享圖片

運行結果:

技術分享圖片

方法區

和java堆一樣,方法區是一塊所有線程共享的內存區域,它用於保存系統的類信息,方法區(永久區)可以保存多少信息可以對其進行配置,在默認情況下,-XX:MaxPermSize為64M,如果系統運行時產生大量的類,就需要設置一個相對合適的方法區,以免出現永久區內存溢出的問題。

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

JVM虛擬機(三):參數配置