java基础-JVM

27 阅读6分钟

前言

13

JVM的主要组成部分有哪些?

  • 类加载器:负责将字节码文件加载到内存中;
  • 运行时数据区:用于保存java程序运行过程中需要用到的数据和相关信息;
  • 执行引擎:特定的命令解析器执行引擎将字节码翻译成底层系统指令;
  • 本地库接口:被执行引擎调用参与字节码的翻译。

运行时数据区的组成部分有哪些?

运行时数据区由五部分构成:方法区本地方法栈程序计数器

  1. :存放对象;
  2. 方法区:存储字节码文件、常量、静态变量、运行时常量池;
  3. :是程序方法运行的主要区域,栈里面存的是栈帧;
  4. 本地方法栈:与栈功能相同,但他执行的是本地方法;
  5. 程序计数器:用于记录正在执行的字节码指令的地址,是线程的私有内存,不会产生内存溢出。

堆和栈的区别是什么?

  1. 栈内存一般会用来存储局部变量和方法调用,但堆内存是用来存储Java对象和数组的;
  2. 堆会GC垃圾回收,而栈不会;
  3. 栈内存是线程私有的,而堆内存是线程共有的。

JVM的类加载器有哪些?

类加载器的主要作用是将字节码文件加载到内存中,主要划分为四种类加载器:

  1. 启动类加载器(BootStrap ClassLoader):负责加载JRE\lib目录中的类;
  2. 扩展类加载器(ExtClassLoader):负责加载JRE\lib\ext目录中的类;
  3. 应用类加载器(AppClassLoader):负责加载用户路径(ClassPath)上的类;
  4. 自定义类加载器:自定义类继承ClassLoader,实现自定义类加载规则。

什么是双亲委派模型?

双亲委派模型是Java中的一种类加载机制。类加载器之间形成了一种层次继承关系,加载时先交给其父类完成,完成不了再尝试执行。在实际执行过程中,会按照自定义类加载器-->应用类加载器-->扩展类加载器-->启动类加载器的顺序从后往前开始询问加载。

类加载器的双亲委派模型保障了jdk自带的类不会被覆盖,使用不同的类加载器最终得到的都是同一个对象。

说一下类加载器的执行过程?

类加载器的执行过程包括了5个阶段:加载验证准备解析初始化

  1. 加载:获取字节码文件;

  2. 验证:验证字节码文件是否符合要求;

  3. 准备:为类变量分配内存并设置类变量的初始值;

  4. 解析:将符号引用替换为直接引用;

  5. 初始化:执行类构造器方法的过程,是类加载的最后一步。

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

  • 引用计数法:两个对象相互引用始终无法释放counter,则永远不能GC,现在已经不怎么用了;
  • 可达性分析算法:GC RootsList对象)为空时,下面创建的对象就将被回收。

JVM的垃圾回收算法有哪些?

有四个,分别是:标记清除算法标记-整理算法复制算法分代收集算法

  • 复制算法:空间一分为2,每次只用其中一半,第一块内存用完,把存货对象复制到另一块内存上,清除剩余可回收对象。简单高效但浪费了一半内存;
  • 分代收集算法:将堆区划分为新生代老年代(1:2),新生代分为伊甸区和两个幸存区(8:1:1)。在伊甸区创建对象,回收对象直接删掉,未被回收的放入幸存区,当回收次数过多放入老年代中,在其中在进行清除。

JVM的垃圾回收器都有哪些?

  1. 整堆回收器G1

  2. 新生代垃圾回收器:一般采用的是复制算法,效率高但是内存利用率低;

  3. 老年代垃圾回收器:一般采用的是标记-整理的算法进行垃圾回收。

Minor GC(新生代)与Major GC(老年代)分别发生在何时?

  • Minor GC:年轻代空间不足时,会触发老年代;
  • Major GC:老年代空间不足时,会先尝试触发年轻代,若之后空间还不足,会触发老年代。

哪些情况会触发类加载机制?

  • 在遇到newputstaticgetstaticinvokestatic字节码指令时,如果类尚未初始化,则需要先触发初始化;
  • 对类进行反射调用时,如果类还没有初始化,则需要先触发初始化;
  • 初始化一个类时,如果其父类还没有初始化,则需要先初始化父类;
  • 虚拟机启动时,需要指定一个包含main()方法的主类,虚拟机会先初始化这个主类。

哪些变量可以作为GC Roots?

  1. 虚拟机栈中 (栈帧中的本地变量表) 引用的对象;

  2. 方法区中类静态属性引用的对象;

  3. 方法区中常量的引用对象;

  4. 本地方法栈中引用的对象。

介绍一下JVM的空间分配担保机制

JVM的空间分配担保机制是什么

JVM的空间分配担保机制确保了在Minor GCMajor/Full GC之间有足够空间处理对象晋升和分配,它的作用是避免在垃圾收集过程中出现内存不足的情况。

工作原理

  1. 估算新生代存活对象的大小:在每次Minor GC前,JVM会估算新生代中存活对象的大小;
  2. 判断老年代的剩余空间:根据估算的存活对象大小,JVM会判断老年代是否有足够的空间来容纳这些晋升的对象;
  3. 触发Full GC的条件:如果老年代空间不足以容纳新生代中晋升的对象,JVM会触发一次Full GC

JDK版本差异

JDK 6之前

担保失败处理:如果老年代最大可用连续空间小于新生代所有对象总空间,虚拟机会检查-XX:HandlePromotionFailure设置。

JDK 7及之后

策略调整:取消了-XX:HandlePromotionFailure选项,每次Minor GC前都会判断老年代剩余最大连续空间是否大于历次Minor GC晋升的平均大小或大于新生代所有对象的大小总和。