一、JVM【JDK8】
1.1 JVM结构图
1.2 GC Roots的理解
思路就是通过一系列名字为“”GC Roots“”的对象作为哦起点,开始向下搜索,如果一个对象到GC Roots没有任何引用链连接时候,则说名对象不可用。也即给他一个集合的引用作为跟出发,通过引用关系遍历对象图,能被遍历到的对象被判断为存活,没有的话就是死亡。
可以作为GC Roots的对象
虚拟机栈中的对象
方法区中的类静态属性引用的对象
方法区中常量引用的对象
本地方法栈中Native引用的对象
1.3 JVM调优的标配参数和X,XX参数
标配参数: java -version java -help
X参数:【了解】 -Xint: 解释执行 -Xcomp: 第一次使用编译成本地代码 -Xmixed:混合模式【默认的】
XX参数: Boolean类型 -XX:+或者-某个属性值,+代表开启,-代表关闭 如何查看是否开启了某个参数
jps -l
jinfo -flag PrintGCDetails 4526
// 结果如下:
-XX:+PrintGCDetails
表示激活了打印GC信息
KV设置类型 -XX:属性key=属性值value 如何设置元空间的大小???
jps -l
jinfo -flag MetaspaceSize 6350
// 默认21M
-XX:MetaspaceSize=21807104
// 程序运行调成1G
-XX:MetaspaceSize=1024m
jinfo举例
-Xms: -XX:InitialHeapSize -Xmx:-XX:MaxHeapSize
1.4 JVM初始默认值
1.5 JVM常用调优参数
-Xms: -XX:InitialHeapSize 初始堆内存【存储空间】
-Xmx:-XX:MaxHeapSize 最大堆内存
-Xss:-XX:ThreadStackSize 设置单个线程栈空间的大小,一般默认为512k-1024k【运行空间】
一般0为出事的默认值
**-Xmn:**设置年轻代的大小
-XX:MetaspaceSize 设置元空间的大小,元空间不在虚拟机中,而是使用的是本地内存,仅受本地内存的限制。默认使用了20m左右
-XX:+PrintGCDetails 打印垃圾回收的细节情况
// 模拟产生OOM的情况下,查看垃圾回收的细节
JVM配置 -Xms:10m -Xmx:10m -XX:+PrintGCDetails
程序设置50M大小的对象
byte[] byteArray = new byte[50 * 1024 * 1024];
GC类型:
FullGC:
-XX:SurvivorRatio
-XX:NewRatio
-XX:MaxTenuringThreshold 设置垃圾回收的最大年龄
二、强、软、弱、虚引用
2.1 强引用Reference
当内存不足的时候,对于强引用对象,就算是出现OOM也不会对该对象进行回收。把一个对象赋值给一个引用变量,这个变量就是一个强引用。该对象的以后永远不会被JVM回收,经常造成内存泄漏OOM。
如果没有引用才可以被回收。
2.2 软引用SoftReference
当内存足够不回收,不够就要回收,尽量不要OOM。
结果:一个null 一个 有值
当内存不够用时候呢?
配置小内存,大对象试试
结果:就发生了OOM,后面两个输出均为null
2.3 弱引用WeakReference
只要有弱引用就会回收,不管内存够不够用。
java.lang.ref.WeakReference
结果:后两个全为null
2.4 虚引用PhantomReference
形同虚设,与其他引用均不同,并不会决定对象的生命周期。 必须与引用队列联合使用ReferenceQueue 跟踪回收的状态。
三、GC垃圾回收
3.1 垃圾回收算法
1.引用计数 2.复制:内存开销 3.标记清除 :内存碎片 4.标记清除整理
3.2 垃圾回收器
这是垃圾回收算法的实现
1.Serial 串行垃圾回收器
他为单线程环境设计的只是用一个线程进行垃圾回收,会停止所有的用户线程
- JVM参数:-XX:+UseSerialGC
- 开启后默认在Serial(Young区用) + Serial Old(Old区用)的收集器组合
- 新生代和老年代都会使用串行收集回收器,新生代使用复制算法,老年代使用标记-整理算法
2.Parallel 并行垃圾回收器
多个垃圾回收线程,用户线程暂停,适合于科学计算,大数据等弱交互场景。 - 就是串行回收器的并行版本
- JVM参数:-XX:+UserParNewGC
- ParNew(Young区用) + Serial Old的组合,新生代使用赋值算法,老年代使用标机-整理算法
3.CMS 并发标记清除垃圾回收器
用户线程和垃圾回收线程,不一定并行或者交替,适合于高并发场景。
JVM参数:-XX:UseConcMarkSweepGC
【养老区】: 无法整理空间 碎片 4.G1
- 将堆内存分割成不同的区域然后并发的随其进行垃圾回收
- JVM参数:-XX:+UseG1GC
- 横跨young old
- 面向服务器的收集器
- 更高的并发
- 更少的延迟
- 整理空间更快
- 不需要很大的堆内存
- 不会产生很多内存碎片
- 用户可以指定停顿时间
- 目标为取代CMS
- jdk7中有G1,jdk9中变成默认的垃圾回收器来替代CMS
总结:
1: G1能充分利用多CPU、 多核环境硬件优势,尽量缩短STW。
2:G1整体上采用标记-整理算法,局部是通过复制算法,不会产生内存碎片。
3:宏观上看G1之中不再区分年轻代和老年代。把内存划分成多个独立的子区域(Region),可以近似理解为一个围棋的棋盘。 4:G1收集器里面讲整个的内存区都混合在一-起了 ,但其本身依然在小范围内要进行年轻代和老年代的区分,保留了新生代和老年代,但它们不再是物理隔离的,而是一部分Region的集合且不需要Region是连续的,也就是说依然会采用不同的GC方式来处理不同的区域。
5: G1虽然也是分代收集器,但整个内存分区不存在物理上的年轻代与老年代的区别,也不需要完全独立的survivor(to space)堆做复制 准备。G1只有逻辑上的分代概念,或者说每个分区都可能随G1的运行在不同代之间前后切换;
3.3 如何查看默认的垃圾回收器?
最后一个参数就是垃圾回收器的种类
java -XX:+PrintCommandLineFlags -version
3.4 JVM的Server/Client模式
- 32位windows 默认是Client的JVM模式
- 其他操作系统2G内存,2cpu以上的用Server模式
- 64位 仅仅Server
3.5 JVM GC+Springboot部署调参
启动流程
- springboot工程
- maven clean
- maven package
- 微服务启动,同时配置JVM GC的调优参数【内,外】
- java -jar springbootxxxxx.war/jar
调参公式:
java -server JVM参数 -jar springbootxxxxx.war/jar
示例如下
// 1.参数调优
java -server -Xms1024m -Xmx1024m -XX:+UseG1GC -jar springbootxxxxx.war/jar
// 2.查看进程ID
jps -l
// 3.查看信息
jinfo -flags 9969
四、Linux生产服务器变慢如何诊断?
操作步骤:
4.1 整机:top
或者 uptime 也可以 load average: 1.52, 0.98, 0.55 计算负载高: (1.52+0.98+0.55)/3 * 100% > 60%
4.2 CPU: vmstat
// 每2秒采样一次 一共采样3次
vmstat -n 2 3
// 所有的CPU idle空闲虑
mpstat -P ALL 2
// 详细信息
pidstat -u l -p 5103
4.3 内存:free
// 内存 MB单位
free -m
// 查看额外 采样次数2S
pidstat -p 5103 -r 2
4.4 硬盘:df
// 简单方便 GB
df -h
4.5 磁盘IO: iostat
iostat -xdk 2 3
// 磁盘块设备分布
rkB/s每秒读取数据量kB;
wkB/s每秒写入数据量kB:
svctm /O0请求的平均服务时间,单位毫秒:
await l/O请求的平均等待时间,单位毫秒;值越小,性能越好:
util 一秒中有百分几的时间用于/O操作。接近100%时,表示磁盘带宽跑满,需要优化程序或者增加磁盘;
rkB/s、wkB/s根据 系统应用不同会有不同的值,但有规律遵循:长期、超大数据读写,肯定不正常,需要优化程序读取。
svctm的值与await的值很接近,表示几乎没有I/O等待,磁盘性能好,
如果await的值远高于svctm的值,则表示1/O队列等待 太长,需要优化程序或更换更快磁
// 具体信息
pidstat -d 2 -p 5103
4.6 网络IO:ifstat
// 采样频率1S
ifstat 1
评论