Java面试题-JVM篇

JVM是Java运行基础
在这里插入图片描述

1. 知识点详解

1、JVM内存模型

- 线程独占:栈,本地方法栈,程序计数器
- 线程共享:堆,方法区

2、栈

又称方法栈,线程私有的,线程执行方法时都会创建一个栈帧,用来存储局部变量表,操作栈,动态链接,方法出口等信息。调用方法时执行入栈,方法返回时执行出栈。

3、本地方法栈

与栈类似,也是用来保存执行方法的信息,执行Java方法是使用栈,执行Native方法时使用本地方法栈

4、程序计数器

保存着当前线程执行的字节码位置,每个线程工作时都有独立的计数器,只为执行Java方法服务,执行Native方法时,程序计数器为空

5、堆

JVM内存管理最大的一块,堆被线程共享,目的是存放对象的实例,几乎所有的对象实例都会放在这里,当堆没有可用空间时,会抛出OOM异常。根据对象的存活周期不同,JVM把对象进行分代管理,有垃圾回收器进行垃圾的回收管理

6、方法区

  • 又称非堆区,用于存储已被虚拟机加载的类信息,常量,静态变量,即时编译器优化后的代码等数据。1.7的永久代和1.8的元空间都是方法区的一种实现
  • JMM是定义程序中变量的访问规则,线程对于变量的操作只能在自己的工作内存中进行,而不能直接对主内存操作。由于指令重排序,读写的顺序会被打乱,因此JMM需要提供原子性,可见性,有序性保证

2. 说说类加载与卸载

加载过程
其中验证,准备,解析合称链接

  1. 加载机制-双亲委派模式
    双亲委派模式,即加载器加载类时先把请求委托给自己的父类加载器执行,直到顶层的启动类加载器。
    父类加载器能够完成加载则成功返回,不能则子类加载器才自己尝试加载
    优点: 
    	- 避免类的重复加载
    	- 避免Java的核心API被篡改
    
  2. 分代回收
    分代回收基于两个事实:大部分对象很快就不使用了,还有一部分不会立即无用,但也不会持续很长时间
    在这里插入图片描述
    年轻代->标记-复制 老年代->标记-清除
  3. 回收算法
    a. G1算法
  • 1.9后默认的垃圾回收算法,特点保持高回收率的同时减少停顿。采用每次只清理一部分,而不是清理全部的增量式清理,以保证停顿时间不会过长
  • 其取消了年轻代与老年代的物理划分,但仍属于分代收集器,算法将堆分为若干个逻辑区域,一部分用作年轻代,一部分用作老年代,还有用来存储巨型对象的分区
  • 同CMS相同,会遍历所有对象,标记引用情况,清除对象后会对区域进行复制移动,以整合碎片空间
  • 年轻代回收:并行复制采用复制算法,并行收集,会StopTheWorld
  • 老年代回收:会对年轻代一并回收
  • 初始标记完成堆root对象的标记

3. 简述一下JVM的内存模型

JVM内存分为线程私有区和线程共享区

线程私有区

  1. 程序计数器
    当同时进行的线程数超过CPU数或其内核数时,就要通过时间片轮询分派CPU的时间资源,不免发生线程切换。这时,每个线程就需要一个属于自己的计数器来记录下一条要运行的指令。如果执行的是Java方法,计数器记录正在执行的Java字节码地址,如果执行的是native方法,则计数器为空
  2. 虚拟机栈
    线程是私有的,与线程在同一时间创建。管理Java方法执行的内存模型。每个方法执行时都会创建一个栈帧拉存储方法的变量表,操作数栈,动态链接方法,返回值,返回地址等信息。栈的大小决定了方法调用的可达深度(递归多少层次,或嵌套调用多少层其他方法,-Xss参数可以设置虚拟机栈大小)。栈的大小是可以固定的,或者是动态扩展的。如果请求的栈深度大于最大可用深度,则抛出stackOverflowError;如果栈式可动态扩展的,但没有内存空间提供支持,则抛出OOM异常
  3. 本地方法栈
    与虚拟机栈作用类似。但它不是为Java方法服务的,而是本地方法(C语言)。由于规范对这块没有强制要求,不通虚拟机实现方法不同

线程共享区

  1. 方法区
    线程共享的,用于存放被虚拟机加载的类的元数据信息,如常量,静态变量和即时编译器编译后的代码。若要分代,算是永久代(老年代),以前类大多static的,很少被卸载或收集,先回收废弃常量和无用的类。其中运行时常量池存放编译生成的各种常量。

  2. 存放对象实例和数组,是垃圾回收的主要区域,分为新生代和老年代。刚创建的对象在新生代的Eden区中,经过GC后进入新生代的S0区中,再经过GC进入新生代的S1区中,15次GC后仍存在就进入老年代。这是按照一种回收机制进行划分的,不是固定的。若堆的空间不够实例分配,则OOM

4. 说说堆和栈的区别

栈是运行时单位,代表着逻辑,内含基本数据类型和堆中对象引用,所在区域连续,没有碎片;堆是存储单位,代表着数据,可被多个栈共享(包括成员中基本数据类型,引用和引用对象),所在区域不连续,会有碎片

1、功能不同

栈内存用来存储局部变量和方法调用,而堆内存用来存储Java中的对象。无论是成员变量局部变量,还是类变量,他们指向的对象都存储在堆内存中

2、共享性不同

栈内存是线程私有的。堆内存是所有线程共享的

3、异常错误不同

如果栈内存或者堆内存不足都会抛出异常。栈空间不足:java.lang.StackOverFlowError.
堆空间不足:java.lang.OutOfMemoryError

4、空间大小

栈的空间大小远远小于堆的

5. 什么时候会触发FullGC

除直接调用System.gc外,触发FullGC执行的情况有如下四种。

  1. 旧生代空间不足 旧生代空间只有在新生代对象转入及创建为大对象,大数组时才会出现不足的现象,当执行FullGC后空间仍然不足,则抛出如下错误:java.lang.OutOfMemoryError:Java heap space为避免以上两种状况引起的FullGC,调优时应尽量做到让对象在Minor GC阶段被回收,让对象在新生代多存活一段时间及不要创建过大的对象及数组
  2. Permanet Generation空间满

6. 说说对象分配规则

- 对象优先分配在Eden区,如果Eden区没有足够的空间时,虚拟机执行一次Minor GC
- 大对象直接进入老年代(大对象是指需要大量连续内存空间的对象)。这样做的目的是避免在Eden区和两个Survivor区之间发生大量的内存拷贝(新生代采用复制算法手机内存)
- 长期存活的对象进入老年代。虚拟机为每个对象定义了一个年龄计数器,如果对象经过了1次Minor GC那么对象会进入Survivor区,之后每经过一次Minor GC那么对象的年龄加1,直到达到阈值对象进入老年区
- 动态判断对象的年龄。如果Survivor区中相同年龄的所有对象的大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象可以直接进入老年代。
- 空间分配担保。每次进行Minor GC时,JVM会计算Survivor区移至老年区的对象的平均大小,如果这个值大于老年区的剩余值大小则进行一次Full GC,如果小于,检查HandlePromotionFailure设置,如果true则只进行Monior GC,如果false则进行Full GC

7. 如何判断对象可以被回收

判断对象是否存活一般有两种方式:

- 引用计数:每个对象有一个引用计数属性,新增一个引用时计数加1,引用释放时计数减1,计数为0时可以回收。此方法简单,无法解决对象相互循环引用的问题
- 可达性分析:从GC Roots开始向下搜索,搜索走过的路径称为引用链。当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的,不可达对象

8、JVM的永久代中会发生垃圾回收么?

垃圾回收不会发生在永久代,如果永久代满了或者是超过了临界值,会触发完全垃圾回收(Full GC)。

9.你知道那些垃圾回收算法

GC最基础的算法有三种:标记-清除算法,复制算法,标记-压缩算法,我们常用的垃圾回收器一般都采用分代收集算法

  • 标记-清除算法:分为“标记”和“清除”两个阶段:首先标记处所有需要回收的对象,在标记完成后统一回收掉所有被标记的对象
  • 复制算法:
  • 标记-压缩算法,标记过程仍然与“标记-清除”算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存
  • 分代收集算法(Generation Collection),把Java堆分为新生代和老年代,这样就可以按照各个年代的特点采用最适当的收集算法

10. 调优命令有哪些

Sun JDK监控和故障处理命令有jps jstat jmap jhat jstack jinfo

  • jps

11. 常见调优工具有哪些

常用调优工具分为两类,jdk自带监控工具:jconsole和jvisualvm,第三方有:MAT(Memory Analyzer Tool),GChisto

12.Minor GC 与Full GC分别发生在什么时候

新生代内存不够用时发生MGC ,JVM内存不够时发生FGC

13. 你知道哪些JVM性能调优参数?

- 设定堆内存大小:-Xmx:堆内存最大限制
- 设定新生代大小。新生代不宜太小,否则会有大量对象涌入老年代
	-  		-XX:NewSize:新生代大小
	- 		-XX:NewRatio  新生代和老生代占比
	- 		-XX:SurvivorRatio:伊甸园空间和幸存者空间的占比
- 设定垃圾回收器:年轻代用-XX:+UseParNewGC 年老代用-XX:+UseConcMarkSweepGC

14. 虚拟机为什么使用元空间替换了永久代

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值