JVM 什么是调优 ?

  • 吞吐量: 用户代码执行时间/(用户代码执行时间 + 垃圾收集执行时间)
  • 响应时间 = 用户线程停顿的时间
  • STW越短 响应时间越短
    快 ============= 短
确定计算之前,应该确定到底是哪个优先,是计算型任务还是响应型任务
吞吐量优先还是响应时间优先,或者是在满足一定响应时间的基础上,要求达到多大的吞吐量

问题:
科学计算 吞吐量。数据挖掘,thrput。吞吐量优先的一般:(PS+PO)
响应时间:网站 GUI API (1.8 G1)

什么是调优? 分类

1、根据需求进行jvm规划和预调优(业务逻辑)
2、优化jvm运行环境(慢、卡顿)
3、解决jvm运行过程中出现的各种问题(解决oom问题)

调优,从规划开始

  • 调优从业务场景开始,没有业务场景的调优都是耍流氓

概念:QPS(query) 、TPS(transaction)
12306上百万并发

  • 无监控(压力测试,能看到结果)不调优
  • 步骤
    1、熟悉业务场景(没有最好的垃圾回收器,只有最合适的垃圾回收器)
    (1)响应时间、停顿时间 [CMS G1 ZGC] 需要给用户做响应
    (2)吞吐量 = 用户时间/(用户时间+响应时间)[PS]
    2、选定垃圾回收器组合
    3、计算内存需求(经验值1.5G16G)
    4、选定CPU(越高越好)
    5、设定年代大小、升级年龄
    6、设定日志参数
    (1)、-Xloggc:/pot/*/xxx.log -XX:+ -XX:+PrintGCCause
    (2)、或者每天产生一个日志文件
    7、观察日志参数

案例一:垂直电商(只卖某一类商品),最高每日百万订单,订单处理系统需要什么样的服务器配置

很多不同的服务器配置都能支撑服务器配置(1.5G 16G)

  • 最高峰时间 100个订单/秒,(找一小时内的高峰期,1000订单/秒)
  • 经验值 压力测试
  • 非要计算产生一个订单需要多少内存? 512K * 1000 500M内存
    (响应时间)
    专业一点问法:要求响应时间100ms
    压测!

案例二:12306遭遇春节大规模抢票应该如何支撑?

12306中国并发量最大的秒杀网站:
号称并发量100W最高
CDN-> LVS->NGINX->业务系统->每台机器1W并发(10k问题)100台机器
普通电商订单->下单->订单系统(IO)减库存->等待用户付款
12306的一种可能模型:下单-> 减库存和订单(redis、kafka)同时异步进行->等付款
减库存最后还会把压力压到一台服务器(RPC)
可以做分布式本地库存+单独服务器做库存均衡
大流量的处理方法:分而治之

优化环境

有一个50万pv的资料类网站原服务器源服务器32位,1.5G的堆,用户反馈网站比较缓慢,因此公司决定升级服务器64位,16G的堆,用户反馈网站卡顿十分严重,反而比以前效率更低了
1、为什么原网站慢,
很多用户浏览数据,很多数据load到内存,内存不足,频繁GC,STW时间长,响应时间变慢
2、为什么会更卡顿
内存越大,FGC时间越长
3、咋办?
PS -改为–> PN + CMS或者G1
如何优化

2、系统CPU经常100%,咋办?(面试高频)
cpu经常100%说明一定有线程在占用系统资源
(1)、找出哪个进程cpu高(top)
(2)、该进程中哪个线程cpu高(top -Hp)
(3)、导出该线程的堆栈(jstack)
(4)、查看哪个方法(栈帧)消耗时间(jstack)
(5)、工作线程占比高 | 垃圾回收线程占比高

3、系统中内存飙高,如何查找问题?(面试高频)
(1)、导出堆内存(jmap)
(2)、分析(jhat jvisualvm mat jprofiler …)

4、如何监控jvm
jhat jvisualvm jprofiler arthas top

解决jvm运行中的问题

一个案例理解常用工具

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class T5_FullGC_Problem01 {
    
    

	private static class CardInfo{
    
    
		BigDecimal price = new BigDecimal(0.0);
		String name = "张三";
		int age = 5;
		Date birthdate = new Date();
		public void m(){
    
    }
	}
	private static ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(50
			,new ThreadPoolExecutor.DiscardOldestPolicy());
	public static void main(String[] args) throws InterruptedException {
    
    
		executor.setMaximumPoolSize(50);
		for(;;){
    
    
			modelFit();
			Thread.sleep(100);
		}
	}
	private static void modelFit(){
    
    
		List<CardInfo> taskList = getAllCardInfo();
		taskList.forEach(info ->{
    
    
//			do something
			executor.scheduleWithFixedDelay(()-> {
    
    
//				do sth with info
				info.m();
			},2,3, TimeUnit.SECONDS);
		});
	}
	private static List<CardInfo> getAllCardInfo(){
    
    
		List<CardInfo> taskList = new ArrayList<>();
		for (int i = 0; i < 100; i++) {
    
    
			CardInfo ci = new CardInfo();
			taskList.add(ci);
		}
		return taskList;
	}
}

  • 2、 java -Xms200M -Xmx200M -XX:+PrintGC T5_FullGC_Problem01
  • 3、一般是运维团队首先受到报警信息(CPU Memory)
  • 4、top命令首先观察到问题:内存不断增长,cpu占用率居高不下
  • 5、top -Hp 观察进程中的线程,哪个线程CPU和内存占比高
  • 6、命令:jps查看java进程,定位具体进程;
    jstack查看该线程的堆栈,定位线程状况
  • 重点关注:WAITING BLOCKED
    eg.waiting on <0x0000000088ca3310> (锁在的地方)(a java.lang.Object)
    假如有一个进程中100个线程,很多线程都在waiting on ,一定要找到是哪个线程持有这把锁
    怎么找?搜索jstack dump的信息,找 ,看哪个线程持有这把锁RUNNABLE
    作业:1:写一个死锁程序,用jstack观察 2 :写一个程序,一个线程持有锁不释放,其他线程等待
  • 7、为什么阿里规范里规定,线程的名称(尤其是线程池)都要写有意义的名称(方便错误定位)怎么样自定义线程里的线程名称(自定义ThreadFactory)
  • 8、oom jinfo pid
  • 9、jstat -gc 动态观察gc情况/ 阅读GC日志发现频繁GC / arthas观察(ali) / jconsole(jdk自带)/jvisualVM/ Jprofiler(最好用,收费)
  • Java Management Extensions (JMX)
    JMX最常见的场景是监控Java程序的基本信息和运行情况,任何Java程序都可以开启JMX,然后使用JConsole或Visual VM进行预览
    你是如何定位oom问题的(图形界面)
    1)、已上线的不用图形界面用什么?(cmdline arthas)
    2)、图形界面用在什么地方?测试! 测试的时候使用(压测观察)
  • 10 jmap -histro 1736 | head -20 查找有多少对象产生
  • 11

Guess you like

Origin blog.csdn.net/lxpeifa/article/details/120096535