JVM调优

一、什么是JVM调优?

根据需求进行预规划

运行中的JVM环境优化

解决JVM运行过程中出现的各种问题

二、垃圾回收器组合参数设定:

1、常见垃圾回收器组合及其参数怎么设置:

-XX:+UseSerialGC:   相当于SerialNew  +  SerialOld的组合,单线程,适用于客户端程序

-XX:+UseParNewGC:  相当于ParNew  + SerialOld组合(老年代默认是SerialOld),该组合已经很少用,部分版本已经废弃;

-XX:+UseConc(urrent)MarkSweepGC: (有些版本可能写法不一样,需要加urrent)相当于ParNew + CMS + SerialOld(当CMS并发失败的时候会启用SerialOld);

-XX:+UseParallelGC: 相当于Parallel Scavenge + Parallel Old   SerialOld  (1.7以前的版本)

-XX:+UseParallelOldGC: 相当于Parallel Scavenge  +Parallel Old(1.8以上的版本,相当于PS + PO组合);

-XX:+UseG1GC:   就是Garbage First;

2、在Linux中怎么查看GC的设置:

java  +XX:+PrintCommandLineFlags  -version

3、HotSpot参数分类:

标准参数:以-开头,所有的HotSpot都支持

非标准参数:-X开头,特定版本执行

不稳定参数:以-XX开头

设置某个参数打开用+,关闭某个参数值用-,如:+UseG1GC和-UseG1GC

4、内存溢出和内存泄漏

内存溢出:Out Of  Memary,是指内存空间已经被占用满了无法再分配新的对象;

内存泄漏:Memary Leak,是指有部分对象占用某块内存,不释放也不回收,一直在那占着,少量的内存泄漏并不会导致内存溢出,大量的内存泄漏可能会导致空间被占满,内存溢出;

5、常见参数设定:

一些常见的JVM参数设置:

java -XX: +PrintCommandLineFlags    Test        运行Test这个类的main方法时,打印相关参数;

-Xmn10      新生代内存,n代表new

-Xms40      初始堆内存

-Xmx40      最大堆内存

-XX: +PrintCommandLineFlags    开启打印参数

-XX:+PrintGC  Test     开启打印GC的信息                     

-XX:+PrintGCDetails   打印GC的详细信息

-XX:+PrintGCTimestamps  打印GC的时间戳

-XX:+PrintGCCauses  打印GC的原因;

-XX:PrintFlagsInitial 

-XX:PrintFlagsFinal   查询全部的、最终的JVM参数,在linux上可以使用grep进行过滤,有七八百个参数:

注意:初始堆内存和最大堆内存一般情况下设置一样大小,如果不设置一样,在内存分配的时候会进行弹性的伸缩,占用计算资源进行内存的扩展和收缩;

6、实战(GC设置及GC信息打印解读):

1、代码:

 public static void main(String[] args) {
        System.out.println("===执行循环===");
        //声明链表
        List list = new LinkedList();
        for (; ; ) {
            //不停地往里面添加数据,每次1M,直到内存溢出
            byte[] bytes = new byte[1024 * 1024];
            list.add(bytes);
        }
    }

2、Idea设置VM参数:

3、运行及运行结果:

4、上述结果打印的是简版的GC回收信息,-XX:+PrintGCDetails  (Idea有提示)打印的是详细的GC回收信息:

5、将垃圾回收器设置为CMS:

同样的代码,CMS的回收次数更多:

三、调优之前的准备:

1、吞吐量:

用户代码执行时间  /  (用户代码执行时间 + 垃圾回收时间)

也就是执行用户代码的时间占总时间的比值,执行用户代码所用的时间越多,说明执行有效业务的时间越多;可以理解为用户代码执行时间的占比,就是到底是用户代码执行时间多还是垃圾回收时间多,(频繁GC的情况下,用户代码执行的时间占比就会减少)

2、响应时间:STW越短,停顿时间越短,响应越快

  • 所谓调优,是指在二者之间,根据业务进行一个平衡和调整。
  • 首先得根据业务确定程序追求的是吞吐量还是响应时间
  • 数据分析,计算,数据挖掘一般都追求吞吐量,在垃圾回收器上首选PC +PO;
  • 用户网站,API接口服务,一般追求响应时间,1.8以上可以选ParNew + CMS,或者直接选G1

四、调优:

1、根据需求进行预规划

2、运行中的JVM环境优化

3、解决JVM运行过程中出现的各种问题(比如OOM)

4、对高并发的理解:百万并发是指在1秒钟内,100万个订单同时下下来,也就是TPS,订单提交到持久化过程结束,淘宝最高峰的并发才五六十万,百万并发也是扯淡,12306才能达到;1000的并发已经很不错了

5、调优前必须进行压力测试

6、调优前进行业务规划优化

7、调优步骤:

  • 熟悉业务场景
  • 选定垃圾回收器(响应时间 or 吞吐量优先)
  • 计算内存需求(只能大概估算,比如一个请求需要占用多少内存(分配多少个对象))
  • 选定cpu,越高越好,cpu核数高,回收越快
  • 设置GC日志参数:(多个日志文件,并循环使用)

五、预调优

调优案例分析:

1、案例1:

百万订单的垂直电商(只卖某类商品),订单系统需要什么样的服务器配置?

分析:

  • 每天百万订单,平均到各个时间点,找到一个小时内最高峰的那个点的TPS
  • 计算一个订单需要多少内存?512K?不好预估
  • 可以要求响应时间在多少毫秒内?进行压力测试

2、案例2:12306春节大规模抢票(更偏向于架构的设计)

  • 秒杀系统:CND(各地CND进行缓存) --> LVS--->nginx--->业务系统
  • 用Redis抗高并发,单机Redis能支撑1W并发,下订单-减库存-等待用户付款使用异步进行
  • 大流量的处理办法:进行分流
  • 当出现数据倾斜的时候,有一台专门的服务器进行数据的平衡调度;

3、优化JVM运行环境(慢和卡顿)

面试问题一:

一个在线文档浏览网站,单节点,升级了系统资源(内存)反而卡顿频繁?

因为在线文档需要把文档Loading到内存,对象比较大,一般直接分配到老年代,回收次数频繁,但因为内存小,所以回收时间短,卡顿不明显,反而内存大的时候,回收一次的耗时要比回收多次的STW长,造成资源升级了反而卡顿;

解决:

  • 在部署方式上,采用多个JVM组成逻辑集群+反向代理的方式,每个JVM仍然是升级前的内存,进行集群部署;
  • 每个JVM在选择垃圾回收器时,选择响应优先的垃圾回收器,比如ParNew+CMS,和G1;

面试问题二:

  • 系统CPU经常100%,如何查找,如何调优?(相对内存占满简单)

一定是由线程一直占用系统资源

1、找出占用cpu的进程,使用top命令找出cup占用最多的进程

2、找出进程中哪个线程占用高?top -Hp  PID查看PID进程中的所有线程,看进程中哪个线程占比高,记录线程号(也是PID)

3、如果是java程序,导出该线程的堆栈信息,jstack  -l  pid导出线程堆栈信息

4、jstack会输出线程状态,如果一直waiting或者blocked,说明那个线程可能有问题(堆栈信息中的线程号是16进制,需要转成10进制才能与top -Hp中的线程号对应起来)

jstack  -dump

堆栈信息中,重点看waiting  on<0x00000123>说明这个线程在等待某个锁,找到哪个线程持有这个锁没释放,<0x00000123>就是那个锁对象

5、可能是工作线程占比高,也可能是垃圾回收线程占比高

为什么阿里的规范里面,要求写线程或线程池的时候,要求自定义线程的名称?

就是为了方便定位OOM问题

  • 系统内存飙高,如何查找,如何解决?

1、同样找出进程和线程

2、导出堆内存,一定是堆内存占用较多

3、分析

面试:有个G1,为什么还要CMS?因为响应时间,G1快一些,但吞吐量G1比CMS少15%

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值