我們在這一篇文章中已經大概瞭解到了jvm的參數有哪些,大概怎麼設置。
JVM調優由淺到深(一)——jvm參數配置
現在我們再來詳細得再更加詳細分析一次;
常用參數設置
設置最大堆內存
參數說明 | 例子 |
---|---|
最大堆內存 | -Xmx10m |
在運行時,可以使用 Runtime.getRuntime().maxMemory() 取得系統可用的最大堆內存。
public void test5(){
System.out.println(Runtime.getRuntime().maxMemory()/1024/1024);
}
運行結果:
設置最小堆內存
參數說明 | 例子 |
---|---|
最小堆內存 | -Xms10m |
Java應用程序在運行時,首先被分配-Xms指定的內存大小,並儘可能嘗試在這個空間段內運行程序。
當-Xms指定的內存大小確實無法滿足應用程序時,JVM 纔會向操作系統申請更多的內存,直到內存大小達到-Xmx指定的最大內存爲止。
若超過-Xmx的值,則拋出 OutOfMemoryError 異常。
如果 -Xms 的數值較小,那麼JVM爲了保證系統儘可能地在指定內存範圍內運行,就會更加頻繁地進行GC操作,以釋放失效的內存空間。
從而,會增加 Minor GC 和 Full GC的次數,對系統性能產生一定的影響
因此把 -Xms 值設置爲 -Xmx 時,可以在系統運行初期減少 GC 的次數和耗時。
設置新生代
參數說明 | 例子 |
---|---|
新生代 | -Xmn2m |
設置一個較大的新生代會減少老年代的大小,這個參數對系統性能以及 GC 行爲有很大的影響。
新生代的大小一般設置爲整個堆空間的1/4到1/3左右。
在 Hot Spot 虛擬機中,-XX:NewSize 用於設置新生代的初始大小,
-XX:MaxNewSize用於設置新生代的最大值。
但通常情況下,只設置 -Xmn 以及可以滿足絕大部分應用的需要。
設置 -Xmn 的效果等同於設置了相同的-XX:NewSize 和 -XX:MaxNewSize。
若設置不同的-XX:NewSize 和 -XX:MaxNewSize可能會導致內存震盪,從而產生不必要的系統開銷。
設置持久代
持久代(方法區)不屬於Java堆的一部分。在Hot Spot虛擬機中,使用-XX:MaxPermSize可以設置持久代的最大值,使用-XX:PermSize可以設置持久代的初始大小。
JDK1.8取消了PermGen,取而代之的是Metaspace(元空間),
所以PermSize和MaxPermSize參數失效,取而代之的是 -XX:MetaspaceSize
和 -XX:MaxMetaspaceSize。
參數說明 | 例子 |
---|---|
持久代的初始大小 | -XX:MetaspaceSize=64M |
持久代的最大值 | -XX:MaxMetaspaceSize=128M |
持久代的大小直接決定了系統可以支持多少個類定義和多少常量。
對於使用 CGLIB 或者 Javassist 等動態字節碼生成工具的應用程序而言,
設置合理的持久代大小有助於維持系統穩定。
一般來說,設置MaxMetaspaceSize爲64MB已經可以滿足絕大部分應用程序正常工作。
如果依然出現永久區溢出,可以將MaxMetaspaceSize設置爲128MB。
這是兩個很常用的永久區取值。
設置線程棧
線程棧是線程的一塊私有空間。有關描述可以參考前文的“Java虛擬機棧”。
參數說明 | 例子 |
---|---|
線程棧大小 | -Xss1M |
在線程中進行局部變量分配,函數調用時,都需要在棧中開闢空間。
如果棧的空間分配太小,那麼線程在運行時,可能沒有足夠的空間分配局部變量或者達不到足夠的函數調用深度,導致程序異常退出;
如果棧空間過大,那麼開設線程所需的內存成本就會上升,系統所能支持的線程總數就會下降。
由於Java堆也是向操作系統申請內存空間的,
因此,如果堆空間過大,就會導致操作系統可用於線程棧的內存減少,
從而間接減少程序所能支持的線程數量。
當系統由於內存不夠無法創建新的線程時,會拋出 OOM 異常如下:
java.lang.OutOfMemoryError: unable to create new native thread
根據以上內容可知,這並不是由於堆內存不夠而導致的 OOM,而是因爲操作系統內存減去堆內存後,剩餘的系統內存不足而無法創建新的線程。
在這種情況下,可以嘗試減少堆內存,以換取更多的系統空間,來解決這個問題。
如果系統確實需要大量的線程併發執行,那麼設置一個較小的堆和較小的棧,
有助於提供系統所能承受的最大線程數。
堆的內存分配
參數說明 | 例子 |
---|---|
eden區/survivor區 | -XX:SurvivorRatio=8 |
老年代/新生代 | -XX:NewRatio=2 |
參數 -XX:SurvivorRatio 是用來設置新生代中,eden空間和s0空間的比例關係。
s0 和 s1 空間又被稱爲 from 空間和 to 空間。
它們的大小是相同的,職能也是一樣的,並在 Minor GC後,會互換角色。
公式:-XX:SurvivorRatio = eden/s0 = eden/s1
舉例:當設置JVM參數 -Xmn10M -XX:SurvivorRatio=8 就等於設置 eden=8M,s0=1M,s1=1M。
參數 -XX:NewRatio 是用來設置新生代與老年代的比例:
公式:-XX:NewRatio = 老年代 / 新生代
舉例:當設置JVM參數 -Xms18M -Xmx18M -XX:NewRatio=2運行程序時,新生代約佔6MB,老年代約佔12MB。
堆分配參數總結
參數說明 | 例子 |
---|---|
-Xmx | 設置Java應用程序能獲得的最大堆 |
-Xms | 設置Java應用程序啓動時的初始堆 |
-Xss | 設置新生代的初始大小與最大值 |
-Xmn | 設置新生代的初始大小與最大值 |
-XX:NewSize | 設置新生代的大小。 |
-XX:NewRatio | 設置老年代與新生代的比例,它等於老年代大小除以新生代大小。 |
-XX:SurvivorRatio | 設置新生代中eden區和survivor區的比例 |
-XX:MetaspaceSize | XX |
-XX:MetaspaceSize | (Java8)設置永久區的初始值。。 |
-XX:MaxMetaspaceSize | (Java8)最大的持久區大小。 |
-XX:MinHeapFreeRatio | 設置堆空間的最大空閒比例,當堆空間的空閒內存小於這個數值時,JVM便會擴展堆空間 |
-XX:MaxHeapFreeRatio | 設置堆空間的最大空閒比例。當堆空間的空閒內存大於這個數值時,便會壓縮堆空間,得到一個較小的堆。 |
-XX:TargetSurvivorRatio | 設置survivor區的可使用率。當survivor區的空間使用率達到這個值時,會將對象送入老年代。 |
非常感謝以下博主的優秀博客
https://www.cnblogs.com/yueshutong/p/9768298.html