jvm參數(shù)詳解可以參考地址:https://www.cnblogs.com/redcreen/archive/2011/05/04/2037057.html
-xx : 這樣開頭的參數(shù)吟吝,都是系統(tǒng)級(jí)別的配置疏旨,如GC打印日志旺芽、用什么樣的垃圾回收器等。
非-xx : 基本上都是應(yīng)用層面上的配置
堆內(nèi)存的簡單配置參數(shù):
-XX:+PrintGc 尺栖, 虛擬機(jī)啟動(dòng)后只要有GC就打印日志
-XX:+UseSerialGc 冒窍, 配置虛擬機(jī)使用串行回收器
-XX:+PrintGcDetails , 打印詳細(xì)日志
-XX:+PrintCommandLineFlags 勇蝙, 將隱式或者顯示的參數(shù)命令傳給虛擬機(jī)輸出
-Xms:+5m 沫勿, 設(shè)置初始啟動(dòng)堆內(nèi)存為5m;默認(rèn)值是物理內(nèi)存的1/64(<1GB)
-Xmx:+10m 味混, 設(shè)置最大堆內(nèi)存為10m产雹;默認(rèn)值物理內(nèi)存的1/4(<1GB)
package com.test.jvm;
public class Test1 {
public static void main(String[] args) {
// 初始內(nèi)存5m, 最大內(nèi)存20m翁锡, 打印詳細(xì)日志蔓挖,使用串行回收器, 打印參數(shù)命令行(日志的第一行)馆衔;一般情況下xms和xmx配置相等
//-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());
// 當(dāng)初始內(nèi)存不夠后瘟判,會(huì)繼續(xù)申請(qǐng)內(nèi)存
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());
}
}
堆內(nèi)存中新生代的設(shè)置:
- -Xmn,設(shè)置新生代的大小角溃,新生代的大小會(huì)影響老年代的大小拷获,這個(gè)參數(shù)對(duì)系統(tǒng)性能及GC行為有很大的影響,新生代一般設(shè)置為整個(gè)堆空間的1/3到1/4左右减细;
- -XX:NewRatio=老年代/新生代 匆瓜, 用來設(shè)置老年代和新生代的比例,一般為2或者3
- -XX:SurvivorRatio=2 , 用來設(shè)置新生代中eden空間和from/to空間的比例驮吱,等于2
package com.test.jvm;
public class Test2 {
public static void main(String[] args) {
//第一次配置
// 堆初始內(nèi)存和最大內(nèi)存都是20m茧妒, 新生代為1m, 新生代中eden/from 為2
//-Xms20m -Xmx20m -Xmn1m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC
//第二次配置
// 堆初始內(nèi)存和最大內(nèi)存都是20m糠馆, 新生代為7m嘶伟, 新生代中eden/from 為2
//-Xms20m -Xmx20m -Xmn7m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC
//第三次配置
//堆初始內(nèi)存和最大內(nèi)存都是20m, 老年代/新生代 2又碌; 新生代中eden/from 為2
//-Xms20m -Xmx20m -XX:NewRatio=2 -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC
byte[] b = null;
//連續(xù)向系統(tǒng)申請(qǐng)10MB空間
for(int i = 0 ; i <10; i ++){
b = new byte[1*1024*1024];
}
}
}
- -Xss10m 九昧, 指定棧內(nèi)存的大小為10m,整個(gè)參數(shù)決定了函數(shù)可調(diào)用的最大深度(一般不使用毕匀,遞歸調(diào)用時(shí)可能用到)
- -XX:PermSize=64M铸鹰,設(shè)置方法區(qū)(永久代)的初始內(nèi)存為64m,默認(rèn)物理內(nèi)存的1/64
- -XX:MaxPermSize=64M 皂岔, 設(shè)置方法區(qū)(永久代)的最大內(nèi)存為64m蹋笼, 默認(rèn)物理內(nèi)存的1/4 (一般不使用)
- -XX:MaxDirectMemorySize,如果不設(shè)置默認(rèn)最大堆空間躁垛,即-Xmx剖毯。直接內(nèi)存達(dá)到上限時(shí),就會(huì)觸發(fā)垃圾回收教馆。
- -XX:MaxTenuringThreshold=15 逊谋,配置新生代的對(duì)象經(jīng)過多少次GC后,進(jìn)入老年代土铺,默認(rèn)15
- -XX:PretenureSizeThreshold=1000 胶滋,配置多大的對(duì)象直接進(jìn)入老年代,但是一般情況下對(duì)象會(huì)直接進(jìn)入TALB區(qū)悲敷,如下測(cè)試代碼
package com.test.jvm;
import java.util.HashMap;
import java.util.Map;
public class Test3 {
public static void main(String[] args) {
//第一次參數(shù):-Xmx30M -Xms30M -XX:+UseSerialGC -XX:+PrintGCDetails -XX:PretenureSizeThreshold=1000
//這種現(xiàn)象原因?yàn)椋禾摂M機(jī)對(duì)于體積不大的對(duì)象 會(huì)優(yōu)先把數(shù)據(jù)分配到TLAB區(qū)域中究恤,因此就失去了在老年代分配的機(jī)會(huì)
//第二次參數(shù):-Xmx30M -Xms30M -XX:+UseSerialGC -XX:+PrintGCDetails -XX:PretenureSizeThreshold=1000 -XX:-UseTLAB
Map<Integer, byte[]> m = new HashMap<Integer, byte[]>();
for(int i=0; i< 5*1024; i++){
byte[] b = new byte[1024];
m.put(i, b);
}
}
}
TLAB(Thread Local Allocation Buffer)*
即線程本地分配的內(nèi)存,是一個(gè)線程專用的內(nèi)存分配區(qū)域后德,為了加速對(duì)象的分配而生成的部宿,每一個(gè)線程都會(huì)有一個(gè)TLAB,該線程獨(dú)享的工作區(qū)域瓢湃。java虛擬機(jī)使用這種TLAB區(qū)來避免多線程沖突的問題理张,提高了對(duì)象的分配效率。TLAB一般不會(huì)太大箱季,當(dāng)大對(duì)象無法再TLAB分配時(shí),則會(huì)直接分配到堆上棍掐。*
- -XX:+UseTLAB 藏雏,使用TLAB
- -XX:+TLABSize=102400 ,設(shè)置大小為102.4KB
- -XX:TLABRefillWasteFraction=64 ,這是一個(gè)比例值掘殴,默認(rèn)64赚瘦,即如果單個(gè)對(duì)象大于整個(gè)空間的1/64,則直接在堆中創(chuàng)建該對(duì)象。
- -XX:+PrintTLAB 奏寨,查看TLAB信息起意。
package com.test.jvm;
public class Test4 {
public static void alloc(){
byte[] b = new byte[2];
}
public static void main(String[] args) {
//TLAB分配
//參數(shù):-XX:+UseTLAB -XX:+PrintTLAB -XX:+PrintGC -XX:TLABSize=102400 -XX:-ResizeTLAB -XX:TLABRefillWasteFraction=100 -XX:-DoEscapeAnalysis -server
for(int i=0; i<10000000;i++){
alloc();
}
}
}
創(chuàng)建一個(gè)對(duì)象在什么位置,jvm會(huì)有一個(gè)比較詳細(xì)的流程病瞳,根據(jù)數(shù)據(jù)的大小揽咕、參數(shù)的設(shè)置,決定如何創(chuàng)建分配及其位置
開始 → 嘗試棧上分配 → 嘗試TLAB分配 → 是否滿足進(jìn)入老年代 → eden分配 → 結(jié)束
應(yīng)用參數(shù)設(shè)置
可以百度“tomcat性能參數(shù)調(diào)優(yōu)” 例如在linux系統(tǒng)下tomcat參數(shù)簡單配置:
在/tomcat/bin/catalina.sh文件中添加:
JAVA_OPTION="-Xms1024m -Xmx1024m -XX:MaxPermSize=256m"
// 初始堆內(nèi)存和最大堆內(nèi)存為1G套菜,最大方法區(qū)(永久區(qū))內(nèi)存256M
參數(shù)位置如下: