Java虚拟机探究(JVM面试重点)

1.1 JVM组成

JVM包含两个子系统和两个组件,两个子系统为Class loader(类装载)、Execution engine(执行引擎);两个组件为Runtime data area(运行时数据区)、Native Interface(本地接口)。

Class loader(类装载):根据给定的全限定名类名(如:java.lang.Object)来装载class文件到运行时数据区中的方法区。

Execution engine(执行引擎):执行classes中的指令。

Native Interface(本地接口):与native libraries交互,是其它编程语言交互的接口。

Runtime data area(运行时数据区域):这就是我们常说的JVM的内存区域

各部分的作用:首先通过编译器把 Java 代码转换成字节码,类加载器(ClassLoader)再把字节码加载到内存中,将其放在运行时数据区(Runtime data area)的方法区内,而字节码文件只是 JVM 的一套指令集规范,并不能直接交给底层操作系统去执行,因此需要特定的命令解析器执行引擎(Execution Engine),将字节码翻译成底层系统指令,再交由 CPU 去执行,而这个过程中需要调用其他语言的本地库接口(Native Interface)来实现整个程序的功能。

JVM组成部分

1.2 JVM内存区域

JVM的运行时数据区就是JVM的内存区域。按照Java虚拟机规范分为5个部分:

程序计数器(Program Counter Register):当前线程所执行的字节码的行号指示器,字节码解析器的工作是通过改变这个计数器的值,来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能,都需要依赖这个计数器来完成;线程私有,不会发生OOM。

Java 虚拟机栈(Java Virtual Machine Stacks):用于存储局部变量表、操作数栈、动态链接、方法出口等信息;每个方法执行时,JVM都会为其创建一个栈帧(Stack Frame);线程私有。

本地方法栈(Native Method Stack):与虚拟机栈的作用是一样的,只不过虚拟机栈是服务 Java 方法的,而本地方法栈是为虚拟机调用 Native 方法服务的;线程私有。

Java 堆(Java Heap):Java 虚拟机中内存最大的一块,是被所有线程共享的,几乎所有的对象实例都在这里分配内存;通过VM参数(-Xmx最大堆内存分配大小 -Xms初始堆内存分配大小)进行设置

方法区(Methed Area):用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数据。线程共享。

1.3 JVM垃圾回收机制

Java中的垃圾回收机制:在java中,程序员不需要考虑释放一个对象的内存的,而是由虚拟机自动执行。在JVM中有一个垃圾回收线程,它是低优先级的,只在虚拟机空闲或堆内存不足才会触发执行,扫描未被引用的对象进行GC。

如何判断对象可以被回收? 一般有两种方式:
**引用计数器法:**为每个对象创建一个引用计数,有对象引用时计数器 +1,引用被释放时计数 -1,当计数器为 0 时就可以被回收。它有一个缺点不能解决循环引用的问题;

**可达性分析算法:**从 GC Roots 开始向下搜索,搜索所走过的路径称为引用链。当一个对象到 GC Roots 没有任何引用链相连时,则证明此对象是可以被回收的。

垃圾回收的时机?
当堆中的对象没有被引用的时候,就可以被GC,GC过程是由JVM自行控制的,虽然在java程序中可以主动调用System.gc()方法,但实际的触发GC并不一定是立即执行,还是有虚拟机自行控制。

GC的方式、算法?

  1. **标记-清除算法。**标记无用对象,然后进行清除回收。缺点:效率不高,会产生内存碎片且无法清除。
  2. **标记-整理算法。**标记无用对象,让所有存活的对象都向一端移动,然后直接清除掉端边界以外的内存。缺点:所有存活对象都要进行移动,比较消耗性能。
  3. **复制算法。**按照容量划分二个大小相等的内存区域,当一块用完的时候将活着的对象复制到另一块上,然后再把已使用的内存空间一次清理掉。缺点:内存使用率不高,只有原来的一半。
  4. 分代算法。 属于混合使用上述算法的一种GC方式,也是JVM中实际使用的GC算法。根据对象存活周期的不同将内存划分为几块,一般是新生代和老年代,新生代基本采用复制算法,老年代采用标记整理算法。

分代算法

当前商业虚拟机都采用分代收集的垃圾收集算法。分代收集算法,顾名思义是根据对象的存活周期将内存划分为几块。一般包括年轻代、老年代 和 永久代,对不同的代使用不同的GC算法。
在这里插入图片描述
年轻代和老年代的所占内存大小之比为 1:2, 而永久区是使用元空间实现,是逻辑的分区。
其中年轻代中的伊甸区和幸存区的内存大小比为 Eden:S0:S1 = 8:1:1 , S0和S1指的是 From Survivor 和 To Survivor ,这两个区域会相互转化。
年轻代一般使用复制算法(Serial、PerNew和Parallel Scavenge收集器),执行的流程是:
① 把 Eden + From Survivor 存活的对象放入 To Survivor 区;
② 清空 Eden 和 From Survivor 分区;
③ From Survivor 和 To Survivor 分区交换,From Survivor 变 To Survivor,To Survivor 变 From Survivor。

老年代一般采用标记-整理算法(Serial Old和Parallel Old 收集器)或者标记清除算法(CMS收集器)。

新生的对象一般是放在Eden区中,当Eden区中没有内存可供分配对象时就会触发Minor GC,Minor GC使用的就是复制算法,将Eden + From Survivor中存活的对象复制到To Survivor中,并将对象的年龄+1,而当对象的年龄达到15(默认为15)时,就不会被复制到To Survivor区中,而是直接被复制到老年代中,另外当大对象(占用连续内存空间的大对象)被创建时也是直接放到老年代当中,当老年代中没有内存可以存储对象时,便会触发Major GC/Full GC,Full GC使用标记-整理或标记清除算法,是针对老年代的GC,Full GC通常伴随着至少一次的Minor GC,执行时间也比较长。

垃圾收集器分类

由于分代垃圾收集的算法使用,一般我们会根据分代的不同选用不同的收集器配合使用,也可以使用整堆收集器比如G1收集器。
常常使用的垃圾收集器有:
在这里插入图片描述
Serial收集器(复制算法): 新生代单线程收集器,标记和清理都是单线程,优点是简单高效;

ParNew收集器 (复制算法): 新生代收并行集器,实际上是Serial收集器的多线程版本,在多核CPU环境下有着比Serial更好的表现;

Parallel Scavenge收集器 (复制算法): 新生代并行收集器,追求高吞吐量,高效利用 CPU。吞吐量 = 用户线程时间/(用户线程时间+GC线程时间),高吞吐量可以高效率的利用CPU时间,尽快完成程序的运算任务,适合后台应用等对交互相应要求不高的场景;

Serial Old收集器 (标记-整理算法): 老年代单线程收集器,Serial收集器的老年代版本;

Parallel Old收集器 (标记-整理算法):老年代并行收集器,吞吐量优先,Parallel Scavenge收集器的老年代版本;

CMS(Concurrent Mark Sweep)收集器(标记-清除算法):老年代并行收集器,以获取最短回收停顿时间为目标的收集器,具有高并发、低停顿的特点,追求最短GC回收停顿时间。

G1(Garbage First)收集器 (标记-整理算法):Java堆并行收集器,G1收集器是JDK1.7提供的一个新收集器,G1收集器基于“标记-整理”算法实现,也就是说不会产生内存碎片。此外,G1收集器不同于之前的收集器的一个重要特点是:G1回收的范围是整个Java堆(包括新生代,老年代),而前六种收集器回收的范围仅限于新生代或老年代。

1.4 常用的JVM调优方式

JDK 自带了很多监控工具,都位于 JDK 的 bin 目录下,其中最常用的是 jconsole 和 jvisualvm 这两款视图监控工具。
jconsole:用于对 JVM 中的内存、线程和类等进行监控;
jvisualvm:JDK 自带的全能分析工具,可以分析:内存快照、线程快照、程序死锁、监控内存的变化、gc 变化等。

常用的 JVM 调优的参数都有哪些?
-Xms2g:初始化堆大小为 2g;
-Xmx2g:堆最大内存为 2g;

-XX:NewRatio=4:设置年轻的和老年代的内存比例为 1:4;
-XX:SurvivorRatio=8:设置新生代 Eden 和 Survivor 比例为 8:2;
–XX:+UseParNewGC:指定使用 ParNew + Serial Old 垃圾回收器组合;
-XX:+UseParallelOldGC:指定使用 ParNew + ParNew Old 垃圾回收器组合;
-XX:+UseConcMarkSweepGC:指定使用 CMS + Serial Old 垃圾回收器组合;
-XX:+PrintGC:开启打印 gc 信息;
-XX:+PrintGCDetails:打印 gc 详细信息。

本文只为了对知识进行总结,基本上是参考其他文档的内容。
参考文章 : https://mp.weixin.qq.com/s/T2DqgJ9-0QiRZQYUeR3c8w.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值