JVM调优

                                                       **JVM调优**
程序的栈(栈帧)和堆
	栈(每个线程一个) 自动释放
	垃圾:没有任何引用指向的对象

查找垃圾
	引用计数 根可达算法
	
回收算法 Mark-Sweep(标记清除) Copying(拷贝) Mark-Compack(标记压缩)
	Mark-Sweep(标记清除):内存碎片化 
	Copying(拷贝):浪费空间
	Mark-Compack(标记压缩):效率低
	
垃圾回收器
	Serial: 垃圾回收线程干活的时候 业务线程停止 
	Serial Old: 垃圾回收线程干活的时候 业务线程停止  工作在老年代
	Parallel Scavenge:  垃圾回收线程干活的时候 业务线程停止 多线程版本
	Parallel Old: 垃圾回收线程干活的时候 业务线程停止 多线程版本 工作在老年代
	ParNew:多线程的年轻代版本
	CMS: concurrent mark sweep
		垃圾回收线程 业务线程同时执行 并发
		
		concurrent mark sweep:
		初始标记---->并发标记--->重新标记--->并发清理
	三色标记算法(并发标记阶段所采用的算法)
		黑色对象A 自己已经标记 fields都标记完成
		灰色对象B 自己标记完成 还没来得及标记fields
		白色对象D 没有遍历到的节点
		
		第一种情况:B->D 消失 A->D 增加 漏标 解决方案 把A变成灰色(并发标记的漏标情况)	
		 
	CMS方案:Incremetal Update的非常隐蔽的问题:
		并发标记,产生漏标
	
		m1(垃圾回收线程) 正在标记A,已经标记完属性1,正在标记属性2
				m2(业务逻辑线程) 把属性1指向白色对象D
				m3(垃圾回收线程) 把A标为灰色
		m1(垃圾回收线程)认为所有属性标完,把A设为黑色,结果D被漏标		
		所以CMS的remark阶段,必须从头扫描一遍
			
	G1方案
			
JVM调优实战
	java T 启动了一个Java虚拟机 
	Java调优对Java虚拟机设定各种参数
	   java参数三类 java - 标准参数 java -X 非标准参数 java -XX 需要调优的参数
	   
什么是调优
	1 根据需求进行JVM规划和预调优
	2 优化运行JVM运行环境
	3 解决JVM运行过程中出现的各种问题(OOM)
	
JVM调优命令 
	jps ----> Java Processs 列出系统中的Java进程 (jdk命令)
	jinfo ---> JVM的信息 jinfo 进程号 (jdk命令)
	jstat ---> Java的统计信息 jstat -gc 进程号 查看gc信息 (jdk命令)
	
	top 统计消耗资源的进程(Linux命令)
	top -hp -进程号 查看进程里的所有线程(Linux命令)
	
	jstack 进程号 | more 把进程的线程相信信息(Linux命令) 比如查阅死锁
	
OOM定位(OutOfMemoryError)
	1 命令行方式
		jmap -histo 进程号  java process map jmap + 进程号 查看进程中的类的信息 产生多少个对象 占用多少个字节
		jmap -histo 进程号 | head -20 查看前20行
		
图形工具分析
	堆转储文件分析
	jmap -dump:format=b,file=20201108.hprof pid 将堆信息以二进制的文件格式导出
	
	jdk bin目录下的Java VisualVM工具查看
	
线上OOM异常的解决思路 
	线上OOM后  启动之前java
	-Xms20M -Xms20M -XX:+UseParallelGC -XX:+HeapDumpOnOutOfMemoryError
	HeapDumpOnOutOfMemoryError当产生OOM之后 会自动的dump一个文件 把这个dump文件拿下来分析
	
	高可用的情况下 停掉一台 用jmap进行导出 / 压测的时候可以定位出这个问题
	
	测试没有问题 真实环境OOM了
	线上的真实流量进行压测:TcpCopy 线上所有流量拷贝一份 给备用服务器一份  在备份上监测问题
	
Arthas
	arthas 挂在java进程上
	dashboard 仪表盘 查看哪个线程吃CPU
	问: 当系统CPU飙高 你怎么定位问题?
		top 命令查看 哪个进程 如果是java 用arthas 查看那个线程吃CPU 如果不是java 用top -hp -进程号 查看是哪个线程
		如果是java进程 业务线程 (查看线程代码) GC线程(频繁的FullGC)读日志 频繁的FullGC 每次回收1M-2M 内存泄漏 有没有正常回收 如果有 压力很大
	thread 列出所有的线程
	thread 22 查看线程的调用情况
	thread -b 查看是否有死锁
	dump 
	headump=Head dump   将堆信息以二进制的文件格式导出
	jad 类名 类的加载classloader 把整个文件的源代码反编译出来
	redefine /root/TT.class 重定义这个类成功
	全链路追踪和压测 trace 类名 方法名

你可能感兴趣的:(java)