溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

常用的java虛擬機(jī)參數(shù)有哪些

發(fā)布時(shí)間:2021-11-18 10:00:55 來源:億速云 閱讀:126 作者:iii 欄目:編程語言

這篇文章主要介紹“常用的java虛擬機(jī)參數(shù)有哪些”,在日常操作中,相信很多人在常用的java虛擬機(jī)參數(shù)有哪些問題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”常用的java虛擬機(jī)參數(shù)有哪些”的疑惑有所幫助!接下來,請(qǐng)跟著小編一起來學(xué)習(xí)吧!

1. 掌握跟蹤調(diào)試參數(shù)

1.1 跟蹤垃圾回收
1 打印垃圾回收日志:-XX:+PrintGC(在jdk9、jdk10中建議使用-Xlog:gc)

最簡(jiǎn)單的一個(gè)GC參數(shù)是-XX:+PrintGC(在jdk9、jdk10中建議使用-Xlog:gc),使用這個(gè)參數(shù)啟動(dòng)jvm后,只要遇到GC,就會(huì)打印日志。

[GC 4893K->377K(15872K), 0.0006926 secs]

一行記錄表示進(jìn)行了一次GC,該GC記錄顯示,在GC前,堆空間使用量約為4MB,在GC后,堆空間使用量為377KB,當(dāng)前堆空間的總和約為16MB(15872K)。最后顯示的是本次GC所花的時(shí)間。

jdk9、jdk10默認(rèn)使用G1作為垃圾回收器,使用參數(shù)-Xlog:gc來打印GC日志,如下圖所示:

[0.012s][info][gc] Using G1
[0.107s][info][gc] GC(0) Pause Full (System.gc()) 16M->7M(34M) 23.511ms

該日志顯示,一共進(jìn)行了一次GC,在GC前,堆空間使用量為16MB,在GC后,堆空間使用量為7MB,當(dāng)前堆空間總和為34MB。最后,顯示的是本次GC所花的時(shí)間,為23.511ms。

2. 打印垃圾回收日志詳情:-XX+PrintGCDetails(在jdk9、jdk10中建議使用-Xlog:gc*)

如果需要更加詳細(xì)的信息,可以使用-XX:+PrintGCDetails(在jdk9、jdk10中建議使用-Xlog:gc*)參數(shù)。該參數(shù)會(huì)使虛擬機(jī)在退出前打印堆的詳細(xì)信息,詳細(xì)信息描述了當(dāng)前堆的各個(gè)區(qū)間的使用情況。

3. 輸出GC前后堆的信息:-XX:+PrintHeapAtGc(從jdk9起,已刪除該參數(shù))

如果需要更全面的堆信息,還可以使用-XX:+PrintHeapAtGc(考慮到兼容性,從jdk9起,已刪除該參數(shù),查看堆信息可以使用Visual VM)。它會(huì)在每次GC前、后分別打印堆的信息,就如同-XX+PrintGCDetails的最后輸出一樣。

4. 關(guān)注GC引起的應(yīng)用程序停頓

由于GC會(huì)引起應(yīng)用程序停頓,因此還需要特別關(guān)注應(yīng)用程序的執(zhí)行時(shí)間和停頓時(shí)間。使用參數(shù)-XX:+PrintGCApplicationConcurrentTime可以打印應(yīng)用程序的執(zhí)行時(shí)間,使用參數(shù)-XX:+PrintGCApplicationStoppedTime可以打印應(yīng)用程序由于GC而產(chǎn)生的停頓時(shí)間。

5. 跟蹤系統(tǒng)內(nèi)的軟引用、弱引用、虛引用和Finallize隊(duì)列

如果想跟蹤系統(tǒng)內(nèi)的軟引用、弱引用、虛引用和Finallize隊(duì)列,可以打開-XX:+PrintReferenceGC(考慮到兼容性,從jdk9開始已經(jīng)刪除此參數(shù),查看堆信息可以使用Visual VM)開關(guān)。

6. 指定gc日志位置

默認(rèn)情況下,GC的日志會(huì)在控制臺(tái)中輸出,這不便后續(xù)分析和定位問題。所以虛擬機(jī)允許將GC日志以文件的形式輸出,可以使用參數(shù)-Xloggc指定。

比如,使用參數(shù)-Xloggc:log/gc.log(在jdk9、jdk10中建議使用-Xlog:gc:/log/gc.log)啟動(dòng)虛擬機(jī),可以在當(dāng)前目錄的log文件夾下的gc.log文件中記錄所有的GC日志。

1.2 類加載/卸載的跟蹤

java程序的運(yùn)行離不開類的加載,為了更好地理解程序如何執(zhí)行,有時(shí)候需要知道系統(tǒng)加載了哪些類。

  • 跟蹤類的加載與卸載: 可以使用參數(shù)-verbose:class跟蹤類的加載與卸載.

  • 單獨(dú)跟蹤類的加載:可以使用參數(shù)-XX:+TraceClassLoading(在jdk9、jdk10中建議使用-Xlog:class+load=info,跟jdk8中的參數(shù)-XX:+TraceClassLoading效果相同)單獨(dú)跟蹤類的加載。

  • 單獨(dú)跟蹤類的卸載:可以使用參數(shù)-XX:+TraceClassUnloading(在jdk9、jdk10中建議使用-Xlog:class+unload=info,跟jdk8中的參數(shù)-XX:+TraceClassUnloading效果相同)跟蹤類的卸載。

  • -XX:+PrintClassHistogram: 該參數(shù)表示遇到 Ctrl-Break 后打印類實(shí)例的柱狀信息,與 jmap -histo 功能相同

1.3 查看系統(tǒng)參數(shù)

由于目前的java虛擬機(jī)支持眾多的可配參數(shù),不同的參數(shù)可能對(duì)系統(tǒng)的執(zhí)行效果有較大的影響,因此有必要明確當(dāng)前系統(tǒng)的實(shí)際運(yùn)行參數(shù)。虛擬機(jī)提供了一些手段來幫助研發(fā)人員獲得這些參數(shù)。

  • -XX:PrintVMOptions:可以在程序運(yùn)行時(shí)打印虛擬機(jī)接收到的命令行顯式參數(shù)。

  • -XX:PrintCommandLineFlags:可以打錢傳遞給虛擬機(jī)的顯示和隱式參數(shù),隱式參數(shù)未必是通過命令行直接給出的,它可能是在虛擬機(jī)啟動(dòng)時(shí)自行設(shè)置的。

  • -XX:+PrintFlagsFinal:會(huì)打印所有的系統(tǒng)參數(shù)的值,開啟這個(gè)參數(shù)后,虛擬機(jī)可能會(huì)產(chǎn)生500多行輸出,每一行為一個(gè)配置參數(shù)及其當(dāng)前取值。

2. 堆的配置參數(shù)

2.1 初始堆與最大堆

初始堆與最大堆分別使用-Xms-Xmx來指定,如指定初始堆大小為5MB、最大堆大小為20MB:-Xms5m、-Xmx20m。在實(shí)際生產(chǎn)中,為了減少程序運(yùn)行時(shí)垃圾回收的次數(shù),一般直接將初始堆-Xms與最大堆-Xmx設(shè)置為相等。

2.2 新生代配置

參數(shù)-Xmn可以用于設(shè)置新生代的大小,設(shè)置一個(gè)較大的新生代減少老年代的大小,這個(gè)參數(shù)對(duì)系統(tǒng)性能及GC行為有很大的影響。** 新生代的大小一般設(shè)置為整個(gè)堆空間的 1/31/4 **.

參數(shù)-XX:SurvivorRatio 用來設(shè)置新生代中eden區(qū)和from/to區(qū)的比例,它的含義如下:

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

示例:

public class Demo02 {
    public static void main(String[] args) {
        byte[] b = null;
        for(int i = 0; i < 10; i++) {
            b = new byte[2 * 1024 * 1024];
        }
    }
}
(1) 使用參數(shù) -Xmx40m -Xms40m -Xmn2m -XX:SurvivorRatio=2 -XX:+PrintGCDetails 運(yùn)行
[GC (Allocation Failure) [PSYoungGen: 1024K->432K(1536K)] 1024K->432K(40448K), 0.0015289 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
Heap
 PSYoungGen      total 1536K, used 885K [0x00000007bfe00000, 0x00000007c0000000, 0x00000007c0000000)
  eden space 1024K, 44% used [0x00000007bfe00000,0x00000007bfe716b0,0x00000007bff00000)
  from space 512K, 84% used [0x00000007bff00000,0x00000007bff6c010,0x00000007bff80000)
  to   space 512K, 0% used [0x00000007bff80000,0x00000007bff80000,0x00000007c0000000)
 ParOldGen       total 38912K, used 20480K [0x00000007bd800000, 0x00000007bfe00000, 0x00000007bfe00000)
  object space 38912K, 52% used [0x00000007bd800000,0x00000007bec000a0,0x00000007bfe00000)
 Metaspace       used 3066K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 337K, capacity 388K, committed 512K, reserved 1048576K

這里的 eden區(qū)from區(qū) 的比值為2:1,故 eden區(qū) 為1024kb,總可用新生代大小為1024kb + 512kb = 1536kb,新生代總大為1024kb+512kb+512kb=2048kb=2mb.

由于eden區(qū)無法容納任何程序中分配的2MB的數(shù)組,故觸發(fā)了一次新生代gc,對(duì)eden區(qū)進(jìn)行了部分回收。同時(shí),這個(gè)偏小的新生代無法為2MB數(shù)組預(yù)留空間,故所有的數(shù)組都分配在老年代,老年代最終占用20480K空間。

(2) 使用參數(shù) -Xmx40m -Xms40m -Xmn14m -XX:SurvivorRatio=2 -XX:+PrintGCDetails 運(yùn)行
[GC (Allocation Failure) [PSYoungGen: 5477K->2560K(10752K)] 5477K->2568K(37376K), 0.0016892 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [PSYoungGen: 8915K->2592K(10752K)] 8923K->2600K(37376K), 0.0015561 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [PSYoungGen: 9050K->2544K(10752K)] 9058K->2552K(37376K), 0.0009707 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 
Heap
 PSYoungGen      total 10752K, used 6871K [0x00000007bf200000, 0x00000007c0000000, 0x00000007c0000000)
  eden space 7168K, 60% used [0x00000007bf200000,0x00000007bf639d28,0x00000007bf900000)
  from space 3584K, 70% used [0x00000007bf900000,0x00000007bfb7c020,0x00000007bfc80000)
  to   space 3584K, 0% used [0x00000007bfc80000,0x00000007bfc80000,0x00000007c0000000)
 ParOldGen       total 26624K, used 8K [0x00000007bd800000, 0x00000007bf200000, 0x00000007bf200000)
  object space 26624K, 0% used [0x00000007bd800000,0x00000007bd802000,0x00000007bf200000)
 Metaspace       used 2970K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 328K, capacity 388K, committed 512K, reserved 1048576K

本次將新生代擴(kuò)大為14MB(7168k+3584K+3584k=14336K),在這個(gè)參數(shù)下,由于eden區(qū)有足夠的空間,因此所有的數(shù)組都分配在eden區(qū)。但eden區(qū)并不足以預(yù)留10MB的空間,故在程序運(yùn)行期間出現(xiàn)了3次新生代gc.由于每申請(qǐng)一次空間,同時(shí)也廢棄了上一次申請(qǐng)的空間(上一次申請(qǐng)的內(nèi)存失去了引進(jìn)),故在新生代gc中,有效回收了這些失效的內(nèi)存。最終結(jié)果是:所有的內(nèi)存分配都在新生代進(jìn)行,通過gc保證了新生代有足夠的空間,而老年代沒有為這些數(shù)組預(yù)留任何空間,只是在gc過程中,部分新生代對(duì)象晉升到老年代。

(3) 使用參數(shù) -Xmx40m -Xms40m -Xmn30m -XX:SurvivorRatio=8 -XX:+PrintGCDetails 運(yùn)行
Heap
 PSYoungGen      total 27648K, used 23437K [0x00000007be200000, 0x00000007c0000000, 0x00000007c0000000)
  eden space 24576K, 95% used [0x00000007be200000,0x00000007bf8e3510,0x00000007bfa00000)
  from space 3072K, 0% used [0x00000007bfd00000,0x00000007bfd00000,0x00000007c0000000)
  to   space 3072K, 0% used [0x00000007bfa00000,0x00000007bfa00000,0x00000007bfd00000)
 ParOldGen       total 10240K, used 0K [0x00000007bd800000, 0x00000007be200000, 0x00000007be200000)
  object space 10240K, 0% used [0x00000007bd800000,0x00000007bd800000,0x00000007be200000)
 Metaspace       used 3064K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 336K, capacity 388K, committed 512K, reserved 1048576K

在這次執(zhí)行中,由于新生代使用30MB空間,其中eden占24MB(30MB / 10 * 8 ),完全滿足10MB數(shù)組的分配,因此所有的分配行為都在eden區(qū)直接進(jìn)行,且沒有觸發(fā)任何GC行為。因此,from/to和老年代的使用率都為0

由此可見,不同的堆分布情況對(duì)系統(tǒng)會(huì)產(chǎn)生一定的影響。在實(shí)際工作中,應(yīng)該根據(jù)系統(tǒng)的特點(diǎn)做合理的設(shè)置,基本策略是:盡可能將對(duì)象預(yù)留在新生代,減少老年代gc的次數(shù)。

(4) 使用參數(shù) -Xmx40m -Xms40m -XX:NewRatio=2 -XX:+PrintGCDetails

除了可以使用參數(shù) -Xmn 指定新生代的絕對(duì)大小,還可以使用參數(shù) -XX:NewRatio 來設(shè)置新生代和老年代的比例,如下所示:

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

本例中,設(shè)置的老年代與新生代的比例為2:1.運(yùn)行結(jié)果如下:

[GC (Allocation Failure) [PSYoungGen: 10075K->496K(11776K)] 10075K->2552K(39424K), 0.0019760 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [PSYoungGen: 8989K->560K(11776K)] 11045K->4672K(39424K), 0.0015192 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 
Heap
 PSYoungGen      total 11776K, used 5144K [0x00000007bf300000, 0x00000007c0000000, 0x00000007c0000000)
  eden space 10240K, 44% used [0x00000007bf300000,0x00000007bf77a088,0x00000007bfd00000)
  from space 1536K, 36% used [0x00000007bfe80000,0x00000007bff0c010,0x00000007c0000000)
  to   space 1536K, 0% used [0x00000007bfd00000,0x00000007bfd00000,0x00000007bfe80000)
 ParOldGen       total 27648K, used 4112K [0x00000007bd800000, 0x00000007bf300000, 0x00000007bf300000)
  object space 27648K, 14% used [0x00000007bd800000,0x00000007bdc04020,0x00000007bf300000)
 Metaspace       used 3044K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 333K, capacity 388K, committed 512K, reserved 1048576K

此時(shí),堆的大小為40MB,新生代和老年代的比為1:2,故新生代大小為40*(1/3)=14MB(其中,eden約為14MB*(8/10)=11.2MB,from/to大小為14*(1/10)=1.4MB),老年代約為26MB。由于在新生代GC時(shí),from/to空間不足以容納任何一個(gè)2MB數(shù)組,影響了新生代的正?;厥眨试谛律厥諘r(shí)需要老年代進(jìn)行空間擔(dān)保。這導(dǎo)致兩個(gè)2MB數(shù)組進(jìn)入老年代(在新生代gc時(shí),尚有1MB數(shù)組幸存,理應(yīng)進(jìn)入from/to區(qū),而from/to區(qū)只有1.4MB,不足以容納)。

2.3 堆內(nèi)存溢出

在java程序的運(yùn)行過程中,如果堆空間不足,則有可能會(huì)拋出內(nèi)存溢出,簡(jiǎn)稱OOM:

public class Demo03 {
    public static void main(String[] args) {
        Vector vector = new Vector();
        for(int i = 0; i < 25; i++) {
            vector.add(new byte[1*1024*1024]);
        }
    }
}

使用參數(shù) -Xmx20m -Xms20m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./dump.log 啟動(dòng),結(jié)果如下:

java.lang.OutOfMemoryError: Java heap space
Dumping heap to ./dump.log ...
Heap dump file created [19887142 bytes in 0.015 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at jvm.chapter03.Demo03.main(Demo03.java:16)

可以看到,虛擬機(jī)將當(dāng)前的堆棧信息導(dǎo)出,并保存到dump.out文件中。

除了在發(fā)生OOM時(shí)可以導(dǎo)出堆信息,虛擬機(jī)還允許在發(fā)生錯(cuò)誤時(shí)執(zhí)行一個(gè)腳本文件。該文件可以用于崩潰程序的自救、報(bào)警或通知,也可以幫助開發(fā)人員獲得更多的系統(tǒng)信息,如完整的線程保存。

3. 非堆內(nèi)存的參數(shù)配置

3.1 方法區(qū)配置

jdk 1.6jdk 1.7 等版本中,可以使用 -XX:PermSize-XX:MaxPermSize 配置永久區(qū)大小 。其中,-XX:PermSize 表示初始的永久區(qū)大小,-XX:MaxPermSize 表示最大永久區(qū)大小。

jdk1.8 開始,永久區(qū)被徹底移除,使用了新的元數(shù)據(jù)區(qū)存放類的元數(shù)據(jù)。在默認(rèn)情況下,元數(shù)據(jù)區(qū)只受系統(tǒng)可用內(nèi)存的限制,但依然可以使用參數(shù) -MaxMetaspaceSize 指定永久區(qū)的最大可用值。

3.2 直接內(nèi)存配置

在NIO被廣泛使用后,直接內(nèi)存的使用變得非常普遍,直接內(nèi)存跳過了Java堆,使用Java程序可以直接訪問原生堆空間。因此,從一定程度上加快了內(nèi)存空間的訪問速度。

最大可以直接內(nèi)存可以使用參數(shù) -XX:MaxDirectMemorySize 設(shè)置。如果不設(shè)置,默認(rèn)值為最大堆空間,即-Xmx 的值。當(dāng)直接內(nèi)存使用量達(dá)到 -XX:MaxDirectMemorySize 時(shí),就會(huì)觸發(fā)垃圾回收,如果垃圾回收不能有效釋放足夠的空間,直接內(nèi)存溢出依然會(huì)引起系統(tǒng)的OOM.

直接內(nèi)存的訪問速度比堆內(nèi)存快;在申請(qǐng)空間時(shí),堆內(nèi)存的速度遠(yuǎn)遠(yuǎn)快于直接內(nèi)存。因此,直接內(nèi)存適合申請(qǐng)次數(shù)較少、訪問頻繁的場(chǎng)合。如果需要頻繁申請(qǐng)內(nèi)存空間,則并不適合使用直接內(nèi)存。

3. Client與Server:虛擬機(jī)的工作模式

目前,java虛擬機(jī)支持 ClientServer 兩種運(yùn)行模式,使用參數(shù) -client 可以指定使用 Client模式,使用參數(shù) -server 可以指定使用 Server模式 。在默認(rèn)情況下,虛擬機(jī)會(huì)根據(jù)當(dāng)前計(jì)算機(jī)系統(tǒng)環(huán)境自動(dòng)選擇運(yùn)行模式。使用-version參數(shù)可以查看當(dāng)前模式:

java version "1.8.0_201"
Java(TM) SE Runtime Environment (build 1.8.0_201-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.201-b09, mixed mode)

server模式啟動(dòng)較client模式慢,因?yàn)?code>server模式會(huì)嘗試收集更多的系統(tǒng)性能信息,使用更復(fù)雜的算法對(duì)程序進(jìn)行優(yōu)化。因此,當(dāng)系統(tǒng)完全啟動(dòng)并進(jìn)入運(yùn)行穩(wěn)定期后,server模式的執(zhí)行速度會(huì)遠(yuǎn)遠(yuǎn)快于client模式``。對(duì)于長(zhǎng)期運(yùn)行的系統(tǒng)更適合server模式,但對(duì)于用戶界面程序而言,運(yùn)行時(shí)間不長(zhǎng),又追求啟動(dòng)速度,更適合client模式

虛擬機(jī)在server模式client模式下的各種參數(shù)可能會(huì)有很大不同,可以使用-XX:+PrintFlagsFinal查看參數(shù)的默認(rèn)值,這里以查看 CompileThresholdMaxHeapSize 為例,示例如下:

對(duì)于 client模式

 $ java -XX:+PrintFlagsFinal -client -version | grep -E 'CompileThreshold | MaxHeapSize'
     intx CompileThreshold                          = 10000                               {pd product}
    uintx MaxHeapSize                              := 4294967296                          {product}
     intx Tier2CompileThreshold                     = 0                                   {product}
     intx Tier3CompileThreshold                     = 2000                                {product}
     intx Tier4CompileThreshold                     = 15000                               {product}
java version "1.8.0_201"
Java(TM) SE Runtime Environment (build 1.8.0_201-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.201-b09, mixed mode)

對(duì)于 server模式

$ java -XX:+PrintFlagsFinal -server -version | grep -E 'CompileThreshold | MaxHeapSize'
     intx CompileThreshold                          = 10000                               {pd product}
    uintx MaxHeapSize                              := 4294967296                          {product}
     intx Tier2CompileThreshold                     = 0                                   {product}
     intx Tier3CompileThreshold                     = 2000                                {product}
     intx Tier4CompileThreshold                     = 15000                               {product}
java version "1.8.0_201"
Java(TM) SE Runtime Environment (build 1.8.0_201-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.201-b09, mixed mode)

到此,關(guān)于“常用的java虛擬機(jī)參數(shù)有哪些”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI