一、编译器自带的优化
1、方法内联
将方法展开,避免频繁调用函数,每次调用函数就会创建一个栈帧,消耗资源。是否内联需要满足以下条件:
- 热点方法:如果方法体小于325字节会尝试内联,可以使用-XX:FreqInlineSize修改大小
- 非热点方法:如果方法体小于35字节会尝试内联,可以使用-XX:MaxInlineSize修改大小
- 被调用方法运行时的实现可以被唯一确定
public class InlineTest {
public static void main(String[] args) {
long start = System.currentTimeMillis();
long res = 0;
for(int i = 0; i < 100000000; i ++ ){
res += add1(i, i, i, i);
}
long end = System.currentTimeMillis();
// 方法内联了 34ms,add1 12byte, add2 4 byte
// VM options=-XX:+UnlockDiagnosticVMOptions -XX:+PrintInlining
System.out.println("cost time = " + (end - start) + ", res = " + res);
// 设置函数必须不超过1字节才能内联,此时耗时 464ms
// VM options=-XX:+UnlockDiagnosticVMOptions -XX:+PrintInlining -XX:FreqInlineSize=1
}
public static int add1(int a, int b, int c, int d){
return add2(a, b) + add2(c, d);
}
public static int add2(int x, int y){
return x + y;
}
}
二、垃圾回收
1、各场景下使用的垃圾回收策略
- 内存有限:提高对象的回收效率,多回收一些对象,腾出更多内存
- 内存较大、高并发:降低高并发时垃圾回收的频率,让cpu更多地去执行业务为不是垃圾回收
2、哪些区域回收哪些类型的垃圾
- 堆:回收创建的对象
- 方法区:废弃的常量和不需要使用的类
- 栈、本地方法栈、程序计数器:这些随线程死亡而死亡,无需回收
3、分代收集算法调优原则
- 合理设置survivor区域大小,避免内存浪费
- 让GC尽量发生在新生代,尽量减少full GC的发生
4、垃圾回收带来的问题
Stop the World机制,简称STW,即在执行垃圾收集算法时,Java应用程序中除垃圾收集器线程之外的线程都被挂起。如果是一些主备模式的服务器,当进行GC的时候时间过长,可能会造成主备之间切换。
并行收集:多个线程同时进行垃圾收集,此时用户线程还是需要等待垃圾收集完毕才能运行
并发收集:用户线程与垃圾收集线程同时进行
如果内存小于6G,使用CMS;如果内存大于6G使用G1
三、JDK内置工具
- 监测工具:jps、jstat
- 故障排查工具:jinfo、jmap、jstack、jcmd
- 可视化工具:jhsdb、jconsole
1、jps
作用:查看JVM进程状态。直接命令行输入jps即可,与ps -ef | grep java
效果相近
2、jstat
作用:用于监控JVM的各种运行状态。
jsate还可以监测编译、gc等信息,详细参数见博客
四、JVM调优网站
https://opts.console.perfma.com/result/generate/VQ0QL