当前位置:主页 > 查看内容

JVM面经

发布时间:2021-06-03 00:00| 位朋友查看

简介:JVM主要组成部分 Class loader(类加载器)根据给定的全限定名类名来装载class文件到方法区 Execution engine执行引擎执行classes中的指令。 Native Interface(本地接口)与native libraries交互是其它编程语言交互的接口。 Runtime data area(运行时数据区域)……

JVM主要组成部分

Class loader(类加载器):根据给定的全限定名类名来装载class文件到方法区

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

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

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

运行时数据区

程序计数器:当前线程所执行的字节码的行号指示器 2个作用 1记录线程执行位置; 2读取指令
Java 虚拟机栈:用于存储对象的引用,基本数据类型.
本地方法栈:与虚拟机栈的作用是一样的,只不过虚拟机栈是服务 Java 方法的,而本地方法栈是为虚拟机调用 Native 方法服务的;
Java 堆:Java 虚拟机中内存最大的一块,是被所有线程共享的,用于存储实例化对象;
方法区:用于存储 class文件,常量 静态变量与方法

对象的创建的几种方式

使用new关键字
使用Class的newInstance方法
使用Constructor类的newInstance方法
使用clone方法
使用反序列化
为对象分配内存的两种方式 1 指针碰撞 2 空闲列

为什么要进行垃圾回收

随着程序的运行,内存中存在的实例对象、变量等信息占据的内存越来越多,如果不及时进行垃圾回收,必然会带来程序性能的下降,甚至会因为可用内存不足造成一些不必要的系统异常。

优点: 垃圾回收机制有效的防止了内存泄露,可以有效的使用可使用的内存。

大对象直接进入老年代,避免大对象分配内存时由于分配担保机制带来的复制而降低效率

Java 中都有哪些引用类型?

强引用:发生 gc 的时候不会被回收。
软引用:有用但不是必须的对象,在发生内存溢出之前会被回收。
弱引用:有用但不是必须的对象,在下一次GC时会被回收。
虚引用(幽灵引用/幻影引用):无法通过虚引用获得对象,用 PhantomReference 实现虚引用,虚引用的用途是在 gc 时返回一个通知

怎么判断对象是否可以被回收?

一般有两种方法来判断:

引用计数器法:为每个对象创建一个引用计数,有对象引用时计数器 +1,引用被释放时计数 -1,当计数器为 0 时就可以被回收。它有一个缺点不能解决循环引用的问题;
可达性分析算法:从 GC Roots 作为起点,引用链作为路径。当一个对象到 GC Roots 没有任何引用链相连时,则证明此对象是可以被回收的。

内存分配策略

堆内存中还要细分为三个区域: ●新生区(伊甸园区) Young/New ●养老区old ●永久区Perm

大对象直接进入老年代 : 需要大量的连续的内存空间,为了避免大对象分配内存时的分配担保机制带来的复制而降低效率

长期存活对象将进入老年代 :对象在伊甸园区分配,经过新生代垃圾回收,对象还存活则会进入幸存者区,并且对象的年龄会+1经过数次GC后,会晋升到老年代

JVM垃圾回收算法

标记清除

首先标记出所有需要回收的对象,在标记完成后统一回收掉被标记的对象 (老年代)

优点:实现简单,不需要对象进行移动。

缺点:第一个是执行效率不稳定,第二个是内存空间的碎片化问题

标记复制

将可用内存按容量划分为大小相等的两块,每次使用其中的一块,这一块用完了就将还存活者的对象复制到另一块上面 (新生代)

优点:按顺序分配内存即可,实现简单、运行高效,不用考虑内存碎片。

缺点:内存缩小到原来的一半.

不过新生代的98%的对象熬不过第一轮收集. 所以eden区和幸存区大小比例是8:1

标记整理

让所有存活的对象都移向内存空间的一端,然后直接清理掉边界以外的内存 (老年代.)

优点:解决了标记-清理算法存在的内存碎片问题。

缺点:仍需要进行局部对象移动,一定程度上降低了效率。

垃圾回收器 作用:释放和重用资源。

是垃圾回收算法的具体实现

img

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收集器基于“标记-整理”算法实现,也就是说不会产生内存碎片。

为什么元空间会取代永久代

整个永久代有一个JVM本身设置固定大小的上限,无法进行调整,而元空间使用的是直接内存,受本机可用内存限制,出现OOM错误的几率大大降低

;原文链接:https://blog.csdn.net/weixin_45326085/article/details/115566399
本站部分内容转载于网络,版权归原作者所有,转载之目的在于传播更多优秀技术内容,如有侵权请联系QQ/微信:153890879删除,谢谢!

推荐图文


随机推荐