网站、APP、小程序、软件、硬件定制开发,联系QQ:99605319
教程格式: 文档
资源语言: 中文

JVM

基础

类的加载过程

1.java代码

2.打包

maven

jar

war

3.执行

执行class main

引用到其他类通过class字节码一并加入

4.类加载器过程

1.验证

class是否符合JVM规范

比如篡改就无法执行

2.准备

分配空间/默认值

静态变量

3.解析

符号引用替换为直接引用

4.初始化

类 

先初始化父类 

静态变量赋值 

静态代码块

类加载器

ClassLoader

1.Bootstrap 

启动类

加载lib目录

2.Extension 

扩展类

加载llib\ext

3.Application 

应用程序

自己写的代码

4.自定义

自定义

可以做一些class加密等

Tomcat热加载也可以在这里做

双亲委派机制

从下游往上查找

作用:为了避免重复加载类

双亲委派机制

JMM 内存模型

方法区

也叫永久代

也叫metaspace元数据空间

存储:加载到jvm的类

程序计数器

执行class字节码 JVM会用到自己的字节码执行引擎

记录当前执行的字节码指令的位置

也叫虚拟机栈

执行方法会创建栈帧压入JVM

作用:保存局部变量表等(操作数栈、动态链接、方法出口)

存储对象数据

局部变量的引用实例

JVM运行过程

类加载到JVM内存

在方法区里面通过JVM字节码引擎执行main方法

同时程序计数器记录并关联了虚拟机栈

虚拟机栈会压入main方法的栈帧

入栈记录局部变量并引用到堆

访问其他方法的时候会创建栈帧压入到JVM

访问结束的时候出栈

JVM分代模型

年轻代

存活周期极短

使用之后立马就可以回收掉的生存周期极短的对象,针对年轻代的垃圾回收我们称为Minor GC也叫做Young GC

老年代

长期存活的

Old GC

永久代

加载的一些jvm类信息

metaspace GC

JVM

JAVA heap space

理论

垃圾的产生

方法入栈,局部变量压入栈帧,同时指向堆内存地址

堆内存存放实例化对象,在方法运行时创建的加载到堆内存

执行方法完毕后,方法出栈,堆内存至此无局部变量引用,变成垃圾。

虚拟机栈执行完部变量消失则产生堆对象无人引用变成垃圾

什么时候回收

内存满了放不下了

没有引用的对象给回收掉

怎么判断没有被引用

可达性分析算法

没有GC Roots一定回收吗

不一定

重写Object finalize赋值

回收类型

强引用

静态变量

不会回收

软引用

SoftReference修饰

一般不回收

除非内存实在不够用了

弱引用

WeakReference修饰

会回收

虚引用

回收算法

可达性分析算法

一层一层往上游判断看是否有一个GC Roots

局部变量就是可以作为GC Roots

静态变量

总结:只要你的对象被方法的局部变量、类的静态变量给引用了,就不会回收他们。

标记清理算法

先通过可达性分析算法追踪GC Roots的方法,看看各个对象是否被GC Roots给引用了,如果是的话,那就是存活对象,否则就是垃圾对象。

先将垃圾对象都标记出来,然后一次性把垃圾对象都回收掉

内存碎片

复制算法

传统复制算法

把内存分为2块

空间利用率低下会产生大量内存碎片

标记可以回收的对象,复制到另外一块区域全部销毁

优化复制算法

分为3块

1个eden和2Survivor

默认比例:8:1:1

通过可达性分析算法标记存活对象,再通过复制算法把eden和一个survivor存活对象放到另外一个Survivor区。然后删除掉eden和survivor 这样不产生内存碎

Stop the World

系统停止处理请求,垃圾回收完再继续处理

假死

GC时候触发

垃圾器

CMS垃圾回收器

标记清理算法

1.老年代存活对象的数量比较大,复制的性能会变得很差

2.标记清理算法会遗留内存碎片

3.必须配合标记整理算法也就是压缩算法把不连续的内存碎片整理为连续空间 可以设置

CMS回收阶段

1,初始标记

理论

方法的局部变量和类的静态变量是GC Roots

类的实例变量不是GC Roots

仅仅标记GC Roots直接引用

特点

STW

效率快

2,并发标记

理论

标记存活对象和垃圾对象

但是并发运行不停创建新对象没被标记

特点

耗时

存活对象多

GC Roots追踪

对老年代所有对象进行GC Roots追踪,其实是最耗时的

并发运行且不会STW不会对系统造成影响

3,重新标记

理论

第二阶段里有很多没标记出来的对象

需要从新标记

还有一些已有对象可能失去引用变成垃圾

特点

STW

4,并发清理

理论

清理掉标记的垃圾对象

特点

耗时

对象多

消耗cpu资源

并发清理不影响系统运行

Concurrent Mode Failure

理论

浮动垃圾

回收期间,系统程序要放入老年代的对象大于了可用内存空间

结果

Serial Old”垃圾回收器替代CMS

STW

重新进行长时间的GC Roots追踪

所以建议设置阈值参数

ParNew垃圾回收器

复制算法

参数

默认并行线程数

-XX:ParallelGCThreads

默认cpu核 4核就是4个线程

不建议调节

指定ParNew

-XX:+UseParNewGC

特点

适用于小堆

如果存活对象的数量比较大,coping的性能会变得很差

原理

Young GC

一旦Eden区塞满之后,就会触发一次Young GC。


  

Young GC会采用复制算法,从GC Roots(方法的局部变量、类的静态变量)开始追踪,标记出来存活的对象。




然后把存活对象都放入第一个Survivor区域中,也就是S0区域, 接着垃圾回收器就会直接回收掉Eden区和S1里剩余的全部垃圾对象,

G1垃圾回收器

特点

一个垃圾器就可以搞定

设置一个垃圾回收的预期停顿时间

他最大的一个特点,就是把Java堆内存拆分为多个大小相等的Region

理论

Region

回收价值

耗费多长时间

可以回收掉多少垃圾

包含

年轻代

年轻代初始化5%

最大60%

老年代

最大40%

数量内存

JVM最多2048个Region

内存大小必须是2的倍数

动态增加

进入老年代条件

动态规则

年龄

Survivor放不下

大对象

超过了一个Region大小的50%

横跨多个Region来存放

之前不一样新生代、老年代在回收的时候会把大对象Region回收

混合回收

复制算法

和之前区别就是时间设置

尽可能的再预期阈值内回收更多的垃圾

停顿时间

不能设置过大

导致系统运行很久,新生代可能都占用了堆内存的60%了,此时才触发新生代gc

不能设置过小

如果这个参数设置的小了,那么说明每次gc停顿时间可能特别短,此时G1一旦发现你对几十个Region占满了就立即触发新生代gc,然后gc频率特别频繁,虽然每次gc时间很短。

STW

FULL GC/mixed gc

没有空闲Region可以承载自己的存活对象了,就会触发 一次失败

失败则单线程进行标记、清理和压缩整理,空闲出来一批Region和之前cms的cmf是一样的

超过45%就出触发

年轻代和老年代都会进行回收

进入老年代条件

1.存活年龄太大

默认15次

可以设置

2.大对象

3.动态年龄判断规则

超过50%

4.survivor放不下

Minor GC后对象太多无法放入survivor

Full GC的条件

1,超过阈值

2.老年代放不下

3.老年代内存小于历次youngGC平均大小

表现

机器CPU负载过高;


频繁Full GC报警;


系统无法处理请求或者处理过慢

JVM调优

工具

jstat

目标

Young GC的触发频率

新生代对象增长的速率

Young GC的耗时

Young GC后有多少对象是存活

老年代对象增长的速率

Young GC过后有多少对象进入了老年代

Full GC的触发频率

Full GC的耗时

常用命令

jstat -gc PID

知道这些东东就可以合理分配内存

jmap

常用

jmap -histo PID

jmap -dump:live,format=b,file=dump.hprof PID

jhet

jhat dump.hprof -port 7000

MAT

这个比起jhet就强大多了

大对象定位

参数

年轻代

比例

-XX:SurvivorRatio

年龄

XX:MaxTenuringThreshold

大对象

XX:PretenureSizeThreshold

垃圾回收器

UseParNewGC 

老年代

整理

-XX:+UseCMSCompactAtFullCollection

默认打开

Stop the World

整理内存碎片

XX:CMSFullGCsBeforeCompaction

多少次GC整理

默认0

阈值

XX:CMSInitiatingOccupancyFaction

默认92%

垃圾回收器

XX:+UseConcMarkSweepGC

空间担保机制

XX:HandlePromotionFailure

并行初始化标记

-XX:+CMSParallelInitialMarkEnabled

重新标记阶段之前YGC

-XX:+CMSScavengeBeforeRemark

G1

新生代初始占比

XX:G1NewSizePercent

默认5%

新生代最大占比

XX:G1MaxNewSizePercent

不超过60%

还是有eden 和survivor理念

-XX:SurvivorRatio

100个Region里面有多少个eden 多少个survivor

混合回收

XX:InitiatingHeapOccupancyPercent

如果老年代占据了堆内存的45%的Region的时候,此时就会尝试触发一个新生代+老年代一起回收的混合回收阶段

默认值是45%

停顿时间

XX:MaxGCPauseMills

默认200ms

回收次数

XX:G1MixedGCCountTarget

默认值是8次

回收干净,让用户无感

闲出来的Region数量

XX:G1HeapWastePercent

默认值是5%

达到了就就会停止回收

存活对象

XX:G1MixedGCLiveThresholdPercent

默认值85%的

一个Region的存活对象多余85%,你还回收他干什么?这个时候要把85%的对象都拷贝到别的Region,这个成本是很高的。

日志

-XX:+PrintGCDetails 

-XX:+PrintGCTimeStamps

-Xloggc:gc.log

-XX:TraceClassLoading -XX:TraceClassUnloading

就是追踪类加载和类卸载的情况,他会通过日志打印出来JVM中加载了哪些类,卸载了哪些类。

dump

-XX:+HeapDumpOnOutOfMemoryError  

-XX:HeapDumpPath=/usr/local/app/oom

屏蔽

-XX:+DisableExplicitGC

弱引用

SoftRefLRUPolicyMSPerMB

clock - timestamp <= freespace * SoftRefLRUPolicyMSPerMB

模板

“-Xms4096M -Xmx4096M -Xmn3072M -Xss1M  -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFaction=92 -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=0 -XX:+CMSParallelInitialMarkEnabled -XX:+CMSScavengeBeforeRemark -XX:+DisableExplicitGC -XX:+PrintGCDetails -Xloggc:gc.log -XX:+HeapDumpOnOutOfMemoryError  -XX:HeapDumpPath=/usr/local/app/oom”

OOM

Metaspace

java.lang.OutOfMemoryError:Metaspace 

动态生成类cglib

java.lang.OutOfMemoryError:java heap space

高并发请求量过大,导致大量对象存活 内存泄漏,不停的创建对象,被引用

java.lang.StackOverFlowError

一般默认设置每个线程1M

方法调用过多导致压入栈过多内存不够用

遇到过的案例

重试机制

瞬时高并发

try/cach处理

故障

Tomact

Max-http-header-size

重试

jetty

直接内存

Direct buffer memory

survivor设置不合理进入老年代引起的

RPC

A-B B挂

序列化Protobuf不一致

基于Thrift框架自己封装出来的一个RPC框架

序列化失败开辟一个byte[]数组

where

大对象

需要调优

实战

预估内存模型

理论

思路

每个请求的需要耗费多少时间(时间)

每个请求需要多少内存(空间)

每秒钟我们需要处理多少个请求(QPS)

GC

通过上诉就可以估算出

每秒钟生产的垃圾

多久一次youngGC

多久一次OldGC

进入老年代的垃圾

实战

每天上亿请求的电商APP订单系统调优思路

QPS

日活

假设每个用户点击20次请求

500万日活

订单微服务系统

不会每个人都下单所用费用转换率10%

真实日活50万

峰值

APP电商系统场景

一般晚上7点到11点4小时高峰预算

4小时峰值

状态

瞬时高并发

普通高并发

环境

多少台机器部署

算出最终 日活/峰值/机器=每台机器的QPS

内存

订单模型估算比如订单类20个字段

往大了估算*10倍

虚拟机栈局部变量会用掉一些内存

用完就变成垃圾

再往大了估算*20

链路长

修改自己订单状态

推送给第三方服务

短信

仓库

优惠卷

时间

每个请求会执行多久时间

这部分非常用重要

不然会产生大量的对象到达老年代

考虑的问题

通过上诉3大块我们就能估算出合理的GC条件然后进行合理的分配内存

1.多久会触发一次Full GC

2.内存碎片整理的频率应该多高?

3.会发生Concurrent Mode Failure吗?

遇到过的案例

弱引用

system.gc

where大对象

内存泄漏缓存没有LRU

String.split()

OOM

如何解决

日志

那个区域出现异常

栈相关信息

假死

top

cpu

磁盘

内存

网络

原因

内存使用过高

频繁GC STW

过多jvm oom

内存使用过高申请无效被杀

cpu过高回收线程没有资源

分析通过MAT定位大对象




java资源(JVM基础思维导图)网址:https://www.08i8.com/ttkfzy/detail83716.html;转载请注明!


提示:
1、资源共享网(www.08i8.com)java文档教程《JVM基础思维导图》仅供研究学习请勿商用!
2、如果发现本资源违法或侵权请【报告管理员】
3、您所看到的所有资源都是网友分享,资源共享网(www.08i8.com)无法保证都能正常下载使用,
4、如果您发现资源无法下载或无法使用请【报告管理员】,管理员会联系资源发布者补充新资源!
5、如果暂时无法补充新资源,【只退积分!不退款!
6、关注微信公众号:《国资互联联盟》 不迷路!

标签 思维导图

与《JVM基础思维导图》相关的《经验教程》


zygxw
zygxw

0

0

0

( 此人很懒并没有留下什么~~ )
img

JVM基础思维导图

下载积分 钻石会员
5 免费
请您 登录后 下载 !
说明

您下载所消耗的积分将转交上传作者。上传资源,免费获取积分!


首页

栏目

搜索

会员