jvm的知识体系
2022-03-09 08:40:58 0 举报
AI智能生成
JVM
作者其他创作
大纲/内容
类加载机制
图解
装载
1、通过一个类的全限定名获取定义此类的二进制字节流
2、将字节流所代表的的静态存储结构转化为方法区的运行时数据结构
3、在java堆中生成了一个代表这个类的java.lang.Class对象,作为对方法区中这些数据的访问入口
链接
1、验证:保证被加载类的正确性
文件格式验证/元数据验证/字节码验证/符号引用验证
2、准备
为类的静态变量分配内存,并将其初始化为默认值
3、解析
把类中的符号引用转换为直接引用
初始化
对类的静态变量,静态代码块执行初始化操作
类加载器
图解
双亲委派原则
定义
如果一个类加载器在接到加载类的请求时,它首先不会自己尝试加载这个类,而是把这个请求任务委托给父类加载器去完成,一次递归,如果父类加载器可以完成加载任务,就成功返回;只有父类加载器无法完成此加载任务时,才自己去加载。
优势
java类随着加载它的类加载器一起具备了一种带有优先级的层次关系。
例如:java中的Object类,它存放在rt.jar之中,无论哪一个类加载器要加载这个类,最终都是委派给处于模型最顶端的启动类加载器进行加载,因此object类在各种类加载环境中都是同一个类。如果不采用双亲委派模型,那么由各个类加载器自己取加载的话,那么系统中会存在多种不同的Object类
垃圾回收
如何判断一个对象是垃圾
引用计数法
缺点:循环引用无法辨别是垃圾,一旦相互持有引用,就导致对象永远无法被回收
可达性分析
由GCroot出发,开始寻找,看看某个对象是否可达
GC Root:类加载器、Thread、本地变量表、static成员、常用引用、本地方法栈中的变量
垃圾回收算法
标记清除
子主题
复制
标记整理
子主题
分代收集算法
young区:复制算法
old区:标记清除或标记整理
垃圾收集器
1、Serial
单线程的收集、适用于新生代、暂停用户代码
2、Serial Old
子主题
3、ParNew
多线程收集、复制算法、 适用于新生代
4、Parallel
相对于ParNew,更加关注于吞吐量
5、Parallel Old
标记整理的算法
6、CMS
初始标记非常快所以用单线程
7、G1
子主题
子主题
jdk11 增加一个新的 :ZGC
垃圾收集器分类
1、串行收集器
Serial
Serial Old
只能有一个垃圾回收线程执行,用户线程暂停。
适用于内存比较小的嵌入式设备
2、并行收集器
Parallel Scanvenge
Parallel Old
多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态。
适用于科学计算、后台处理等交互场景
3、并发收集器
CMS
G1
用户线程和垃圾收集线程同时执行(但并不一定是并行的,可能是交替执行的),垃圾收集器在执行的时候不会停顿用户线程的运行。
适用于相对时间有要求的场景,比如web
吞吐量和停顿时间
停顿时间->垃圾收集器进行垃圾回收终端应用执行响应的时间
停顿时间越短越适合需要和用户交互的程序,良好的响应速度能提升用户体验
吞吐量->运行用户代码时间/(运行用户代码时间+垃圾收集时间)
高吞吐量则可以高效地利用CPU时间,尽快完成程序的运算任务,主要适合在后台运算而不需要太多交互的任务
两个指标也是评价垃圾回收器好处的标准,其实调优也就是在观察者两个变量。
如何选择合适的垃圾收集器
优先调整堆的大小让服务器自己来选择
如果内存小于100M,使用串行收集器
如果是单核,并且没有停顿时间要求,使用串行或JVM自己选
如果允许时间停顿超过1秒,选择并行或JVM自己选
如果响应时间最重要,并且不能超过1秒,使用并发收集器
性能优化
OOM
内存溢出
用mat工具处理
GC优化
打印GC日志文件
分析工具
gceasy.io
关注点
吞吐量
停顿时间
追求高吞吐量低停顿
性能优化 指南
发现问题
GC频繁
死锁
OOM
线程池不够用
CPU负载过高
排查问题
打印出GC日志,查看minor gc/major gc,结合工具gc viewer/gceasy.io
jstack查看线程堆栈信息
dump出堆文件,使用MAT或者其他工具分析
合理使用jdk自带的jconsole,jvisualvm,阿里的arthas等实时查看JVM状态
灵活应用jps,jinfo,jstat,jmap等常用命令
解决方案
适当增加堆内存大小/选择合适的垃圾收集器
使用zk,redis实现分布式锁
设置本地,Nginx等缓存减少对后端服务器的访问
后端代码优化及时释放资源/合理设置线程池中的参数
集群部署从而减少单节点的压力
利用一些消息中间件比如MQ,Kafka实现异步消息
运行时数据区
堆
所有的对象都在堆里面进行分配
堆是java虚拟机所管理内存中最大的一块
起始:在虚拟机启动时创建,被所有线程共享
java对象实例以及数组都在堆上分配
当堆无法满足内存分配需求时,将抛出OutOfMemoryError
方法区
方法区是各个线程共享的内存区域,在虚拟机启动时创建
存储内容:被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据
方法区记录的是方法以外的一些数据
虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做Non-Heap(非堆),目的是和java堆区分开来
异常产生:方法区无法满足内存分配需求时,抛出OutOfMemoryError异常
jdk的版本区分
jdk8:Metaspace【元空间】
jdk6或7中就是Perm Space【永久代】
Run-Time Constant Pool 在方法区分配
图解
jvm
java虚拟机栈
是什么?
虚拟机栈是一个线程执行的区域,保存着线程中方法的调用状态。
一个java线程的运行状态,由一个虚拟机栈来保存
虚拟机栈肯定是线程私有,独有的,随着线程的创建而创建
栈帧
每个线程执行的方法,为该栈的栈帧,即每个方法的执行对应一个栈帧
细节
每个栈帧对应一个被调用的方法,可以理解为一个方法的运行空间
每个栈帧中包含
局部变量表
操作数栈
图解
子主题
子主题
动态链接
程序运行当中会动态调用某些类的方法
方法返回地址
上一个方法执行完,返回到指定行数
附加信息
调用一个方法,就会向栈中压入一个栈帧;一个方法调用完成,就会把该栈帧从栈中弹出
程序计数器
当前线程所执行方法的位置,在虚拟机栈中 The PC register
一个jvm进程中有多个线程在执行,而线程中的内容是否能够拥有执行权,是根据cpu调度来的。
假如线程A正在执行到某个地方,突然失去了CPU的执行权,切换到了线程B了,然后当xianchengA再获得Cpu执行权的时候,怎么能继续执行呢?这就是需要在线程中维护一个变量,记录线程执行到的位置
假如线程A正在执行到某个地方,突然失去了CPU的执行权,切换到了线程B了,然后当xianchengA再获得Cpu执行权的时候,怎么能继续执行呢?这就是需要在线程中维护一个变量,记录线程执行到的位置
程序计数器的说明
1、程序计数器占用的内存空间很小,由于java虚拟机的多线程是通过线程轮换切换,并分配处理器执行时间来实现的,任意时刻,一个处理器只会执行一个独立的程序计数器(线程私有)
2、如果线程正在执行Java方法,则计数器记录的是正在执行的虚拟机字节码指令的地址
3、如果正在执行的是Navicat方法,则这个计数器为空
线程私有
本地方法栈
图解
jvm内存模型
图解
子主题
子主题
young区
young区分为两大块,一个是Survivor区(s0+s1),一块是Eden区。 Eden:S0:S1 = 8:1:1
为何如此分配?
因为Eden是负责存放新生对象的区域,大部分的对象都是朝生夕死的因此必然会占用大量的Eden区域,而如果变小的话会造成Eden不够使用的情况。Survivor区的存在是为了在GC过程中活下来的作为存留,也是为了避免产生碎片化的空间
Eden
如果没有Eden和survivor区会导致GC后出现空间碎片化,导致空间不连续会造成大的对象可能会过早的分配不下导致过早的GC
正常对象创建所在区域,大多数对象“朝生夕死”
Survivor
Survivor区分为S0和S1,也可以叫From和To
同一时间点上,S0和S1只能有一个区有数据,另外一个是空的,也是为了处理空间碎片化的问题
old
一般old区都是年龄比较大的对象,或者相对超过了某个阈值的对象
Survivor区如果分配不下了会向old区借空间
工具
子主题
命令 jvisualvm
子主题
JVM工具
JVM参数
标准参数
-x参数
-XX参数
-XX:[+/-]
-XX:+UseG1GC
-XX:<name>=<value>
-XX:InitialHeapSize = 100M
其他参数
-Xms100M ==》 -XX:InitialHeapSize=100M
-Xmx100M
-Xss100
JVM命令
jps
可以查看当前的java进程
jinfo
可以查看某个java进程目前参数设置的情况
示例
示例2
示例1
jstat
查看java进程的统计信息
示例
查看当前进程类加载的统计情况 10秒 打印十次
查看当前进程的GC情况
jstack
查看当前java进程的堆栈信息
可以用于查看死锁的情况排查
jmap
打印出堆转存储快照
jmap -heap PID
获取堆内存信息
排查内存泄露
jmap -dump:format=b,file=heap.hprof PID
子主题
idea
常用工具
jconsole
jvisualvm
监听某个java进程
arthas
阿里的一个工具
mat/perfma
内存相关信息
gceasy.io/gcviewer
收藏
收藏
0 条评论
下一页