JVM调优

1、JVM运行时数据区
JVM图
2、基础
(1)、类加载器
(2)、双亲委派
(2)、沙箱机制

3、垃圾回收算法
(1)、引用计数
(2)、复制
(3)、标记清除
(4)、标记整理

4、GCRoot :
(1)虚拟机栈中的引用对象
(2)方法区中的类静态属性引用的对象
(3)方法区中的常量引用的对象
(4)本地方法栈中JNI(native)引用的对象

5、jvm调优参数
在这里插入图片描述

  1. 标配参数(-version,-help)
  2. X参数(Xint,Xcomp,Xmixed)
  3. XX参数(-XX:+/- =)
    -Xms = -XX:+InitialHeapSize 初始化堆内存
    -Xmx = -XX:+MasHeapSize 最大堆内存
    -Xmn = -XX:+ThreadStackSize
    -Xms 默认1/64物理内存
    -Xmx 默认1/4物理内存

jps -l 查看java后台进程
jinfo 正在运行的程序信息
查看jvm 参数
jinfo -flag 参数 进程号,
jinfo -flags 进程号
java -XX:+PrintFlagsInitial JVM初始化家底
java -XX:+PrintFlagsFinal -version
运行java 打出参数
-XX:+PrintCommandLineFlags

-XX:SurvivorRatio=8 eden/survior
-XX:NewRatio=1 老年代/年轻代
-XX:MaxTenuringThreshold=15 survivor取复制15次后进入老年代

-XX:+PrintGCDetails打印GC细节

在这里插入图片描述

在这里插入图片描述

[GC (Allocation Failure) [PSYoungGen: 2048K->506K(2560K)] 2048K->1021K(9728K), 0.0501431 secs] [Times: user=0.00 sys=0.00, real=0.07 secs]
[Full GC (Allocation Failure) [PSYoungGen: 0K->0K(2560K)] [ParOldGen: 1475K->1455K(7168K)] 1475K->1455K(9728K), [Metaspace: 3259K->3259K(1056768K)], 0.0096555 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]

OOM
在这里插入图片描述

  1. java.lang.StackOverflowError:堆栈溢出,线程请求栈深大于jvm最大深度,-Xss配置单个栈大小
  2. java.lang.OutOfMemoryError:Java heap space 堆内存溢出
  3. java.lang.OutOfMemoryError:GC overhead limit exceeded 超过98%的时间用来GC,只回收了2%的对象
  4. java.lang.OutOfMemoryError:Direct buffer memory 本地内存中,不断new出新对象,导致溢出,由于堆内存大小够用不发生GC,netty中出现
  5. java.lang.OutOfMemoryError:unable to create native thread 项目中线程数超过了服务器最大线程数的限制,linux非root用户限制为1024
  6. java.lang.OutOfMemoryError:Metaspace 元空间溢出

JVM参数演示(GC overhead limit exceeded)
-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:MaxDirectMemorySize=5m
GC回收时间过长导致OOM,过长的定义是,超过98%的时间用来GC,只回收了不到2%的堆内存空间,若不抛出
GC overhead limit exceeded 会发生:CPU使用率一直是100%,而GC没有任何成果

Direct buffer memory
nio程序经常使用ByteBuffer来读取或写入数组,这是一个基于通道与缓冲区的I/O方式,他可以使用native函数库直接分配堆外内存,然后通过一个存储在java堆里面的DirectByteBuffer对象作为这块内存的引用进行操作,这样能在一些场景中显著的提高性能,因为避免了在Java堆和native堆中来回复制数据
ByteBuffer.allocate(capability)分配jvm内存,属于GC范畴,由于需要拷贝,速度较慢
ByteBuffer.allocateDirect(capability)分配DS本地内存,不属于GC范畴,速度较快
但如果不断分配本地内存,堆内存很少使用,那么jvm就不需要执行GC,DirectByteBuffer对象就不会被回收,这种情况堆内存充足,本地内存已经用光,在尝试分配内存,就会发生OOM,程序就直接奔溃了

unable to create native thread
应用程序创建太多线程超过系统负载极限
解决:限制创建线程程数,扩大系统线程限制配置

Metaspace 元空间溢出,-XX:MaxMetaspaceSize=5m
java8版本之后使用Metaspace替代永久代,Metaspace不属于虚拟机内存中,而是使用本地内存

垃圾回收器就是GC算法 的落地实现(4种,7大收集器)

Serial (UseSerialGC,UseSerialOldGC)
Parallel(UseParallelGC)
CMS(ConcMarkSweep)(UseConcMarkSweepGC,UseParNewGC)
G1(UseG1GC)
在这里插入图片描述

我们公司的一段jvm配置,使用的CMS收集器
在这里插入图片描述
-XX:+UseConcMarkSweepGC,-XX:+UseParNewGC

gceasy.io网站很好用,一个很好的在线工具配置jvm参数

查看默认的垃圾收集器
$ java -XX:+PrintCommandLineFlags -version
-XX:InitialHeapSize=132860928 -XX:MaxHeapSize=2125774848 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
java version “1.8.0_102”
java8默认用的ParallelScavenge,Parallel Old

  1. Serial:串行收集器
    开启:-XX:+UseSerialGC
    它为单线程环境设计,只使用一个线程进行垃圾回收,会暂停所有用户线程,执行GC
    开启后 Serial(Young区)+Serial Old(Old区)收集器组合
    表示新生代和老年代都会使用串行收集器,新生代用复制算法,老年代用标记整理算法
    -XX:+UseParNewGC 启用ParNew收集器,只影响新生代,不影响老年代。老年代不配的话默认Serial Old, 新生代用复制算法,老年代用标记整理算法

  2. Parallel:并行收集器
    开启:-XX:+UseParallelGC,-XX:+UseParallelOldGC可相互激活,
    多个垃圾收集线程一起执行,也会暂停所有用户线程,
    开启后Parallel Scavenge +Parallel old 收集器组合,
    新生代用复制算法,老年代用标记整理算法
    -XX:ParallelGCThreads=N 表示会使用N个线程执行GC
    CPU>8 N=5/8
    CPU<8 N=实际个数

  3. CMS收集器(ConcurrentMarkSweep并发标记清除)
    开启:-XX:+UseConcMarkSweepGC
    是一种以获得最短停顿时间的收集器,适合互联网或者B/S服务器上,适合内存大,cpu核多的服务器,是G1出现前最适合的垃圾回收器
    开启后 ParNew(Young区)+CMS和Serial(Old区)收集器组合
    新生代用复制算法,老年代用标记清除算法
    大部分互联网公司使用
    缺点:产生大量内存碎片
    在这里插入图片描述

  4. G1收集器
    开启:-XX:+UseG1GC
    充分利用多CPU,多环境优势充分缩短STW(停顿时间)
    使用整体标记整理算法
    优势明显
    STW可控,甚至可以预测GC停顿时间自己设置期望的时间
    原理:
    在这里插入图片描述
    在这里插入图片描述

总结在这里插入图片描述

JVM 结合spring boot参数调优
实际工作中如何进行调优
1.idea开发完微服务工程
2.maven进行clean打包
3.要求微服务启动的时候配置jvm gc的调优配置
4.java -server jvm各种参数 -jar 包名

  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值