admin 管理员组文章数量: 1087677
JVM内功心法
官网:
/
类文件到虚拟机(类加载机制)
(1)装载(Load):查找和导入class文件
1)通过类的全限定名获取此类的二进制字节流;
2)在方法区存放类信息、常量和静态变量;
3)在java堆中生成一个代表这个类的class对象;
(2)链接(Link)
1)验证:保证被加载类的正确性;
2)准备:为类的静态变量分配内存,并初始化为默认值;
3)解析:将符号引用转变为直接引用;(符号引用:以一组符号来描述所引用的目标,可以是任何形式的字面量;直接引用:如指针、地址、相对偏移量等)
(3)初始化:对类的静态变量、静态代码块执行初始化操作;
运行时数据区(Run-Time data area)
类文件被加载进来之后,类中的内容(类的常量、变量、方法、对象等信息)在JVM的对应存放空间;
(1)Method Area 方法区
各个线程共享的区域,在java虚拟机启动时创建。
用于存放被虚拟机加载的类信息、常量、静态变量,即时编译器编译后的静态代码等数据;
GC不会进行回收的区域(非堆),所以当方法区内存无法满足分配需求时,会抛出OutOfMemoryError
常量池用于存放编译时期生成的各种字面量和符号引用
(2)Heap 堆
在虚拟机启动时创建、被所有线程共享,用于存放java对象和数组信息;
(3)Java Virtual Machine Stacks 虚拟机栈
java虚拟机栈是一个线程的执行区域,保存着一个线程中方法的调用状态,是线程私有的,随着线程的创建而创建;每一个被线程执行的方法,对应栈中的一个栈帧,方法调用,向栈中压入一个栈帧,调用完成,把栈帧从栈中弹出;
局部变量表:方法中定义的局部变量以及方法的参数
操作数栈:方法中的操作数,以压栈和出栈的方式存储
动态链接:栈帧指向运行时常量池中该栈帧所属方法的引用
方法返回值
(4)The PC Register 程序计数器
java多线程是通过cpu在不同线程之间轮流切换,并分配处理器执行时间的方式来实现的,任意时间,一个处理器只会处理一条线程中的指令。因此,为了线程切换后能回到原来的执行位置,每条线程需要一个程序计数器来进行记录;
JVM内存模型
注意区别于java内存模型(JMM)
JMM是一个抽象的概念,主要与多线程有关,主要是保证共享内存部分的原子性、可见性和有序性,定义了共享内存中多线程读写程序的行为规范;
JVM内存模型,jvm运行时的内存结构,与Run Time Data Area有关
S0和S1又可以称为from区和to区,身份可互换,两者肯定有一个为空(To区)
一般情况下,新创建的对象会放到Eden区域,一些特殊的大对象直接放到old区域;
young区清理流程
假设开始Eden和from区域有对象,jvm进行Minor GC,两区域对象年龄+1,达到设置或默认的年龄限制(16)之后,进入old区域,未达到的复制到to区域,清空eden和from区,同时to区变为from,from变为to.Minor GC会一直重复上述操作,直到to区满后,全部复制到old区,并清空to。
old区清理
old区域存放的都是年龄较大,或者年龄超过了某个阈值的对象。old区也会有GC操作,称为Major GC,超过了限制的对象则被当成垃圾回收掉。
对象的生命周期
GC过程中如何确定一个对象是垃圾?
1、引用计数法
只要程序中持有该对象的引用,就说明该对象不是垃圾;
弊端:如果AB相互持有,则永远不会被回收;
2、可达性分析
通过GC Root对象开始向下寻找,看某个对象是否可达。
可作为GC Root对象的:类加载器,虚拟机栈的局部变量表,static成员,常量引用,本地方法栈的变量等。
垃圾收集算法
1、标记清除法
找出不需要的对象,进行标记,然后清除
缺点:会产生大量不连续空间碎片
2、复制算法
将内存划分为两块相等的区域,每次只使用其中一块,当其中一块放不下了之后,将还存活的对象连续的复制到另一块,然后全部清除。
缺点:空间利用率降低,每次只能使用一半。
3、标记整理算法
标记过程仍然与"标记-清除"算法一样,但是后续步骤不是直接对可回收对象进行清理,而是让所有存活 的对象都向一端移动,然后直接清理掉端边界以外的内存。
分代收集算法
Young区:复制算法(对象在被分配之后,可能生命周期比较短,Young区复制效率比较高)
Old区:标记清除或标记整理(Old区对象存活时间比较长,复制来复制去没必要,不如做个标记再清理)
垃圾收集器及其分类
1、串行收集器
serial 、serial old
只能有一个垃圾回收线程执行,用户线程暂停。
适用于内存比较小的嵌入式系统
2、并行收集器[吞吐量优先]
parallel scanvenge、parallel old
多条垃圾线程并行工作,但此时用户线程仍处于等待状态。
适用于科学计算、后台处理等交互场景。
3、并发收集器[停顿时间优先]
CMS、G1
用户线程和垃圾收集线程同时执行(但并不一定是并行的,可能是交替执行),垃圾收集线程在执行的时候并不会停止用户线程的运行。
适用于相对时间有要求的场景,比如web应用。
吞吐量:用户线程执行时间/(用户线程执行时间+垃圾收集时间)
停顿时间:垃圾收集器进行垃圾回收,终端应用执行响应的时间
JVM调优
1、JVM参数
(1)标准参数
-version
-help
-server
-cp
(2)-X 参数
非标准参数,在jdk各版本可能会不一样
-Xint 解释执行
-Xcomp 第一次使用就编译成本地代码
-Xmixed 混合模式,JVM自己决定
(3)-XX 参数
非标准参数,相对不稳定,主要用于jvm调优和debug
a.Boolean类型 格式:-XX:[±]
+或-表示启用或者禁用name属性
比如:-XX:+UseConcMarkSweepGC 表示启用CMS类型的垃圾回收器
-XX:+UseG1GC 表示启用G1类型的垃圾回收器
b.非Boolean类型
格式:-XX=表示name属性的值是value
比如:-XX:MaxGCPauseMillis=500
(4)其他参数
-Xms1000等价于-XX:InitialHeapSize=1000
-Xmx1000等价于-XX:MaxHeapSize=1000
-Xss100等价于-XX:ThreadStackSize=100
2、常用命令
1、查看进程
jps
ps -ef | grep tomcat
2、jinfo
实时查看和调整jvm参数
3、jstack
查看虚拟机性能统计信息、类装载信息、垃圾收集信息、线程堆栈信息等
案例:使用jstack查看进程死锁
4、jmap
生成堆转存储快照、打印堆内存相关信息、dump出堆内存相关信息
案例:设置发生oom时自动dump出文件:
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heap.hprof
3、常用工具
1、 jconsole jdk自带,直接命令行输入 jconsole
2、jvisualvm
3、Arthas
阿里巴巴开源,采用命令行交互模式
4、MAT
java堆分析器,用于查找内存泄漏;
本文标签: JVM内功心法
版权声明:本文标题:JVM内功心法 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/b/1694430647a251957.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论