JVM面试题(三)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 二、java 中垃圾收集的方法有哪些?
    • 1. 标记-清除:
    • 2. 复制算法:
    • 3. 标记-整理
    • 4. 分代收集
  • 三、java 内存模型
  • 四、简述 java 类加载机制?
  • 五、类加载器双亲委派模型机制?
  • 六、什么是类加载器,类加载器有哪些?
  • 七、简述 java 内存分配与回收策率以及 Minor GC 和Major GC
  • 总结


前言

  1. 简述 java 垃圾回收机制?
  2. java 中垃圾收集的方法有哪些?
  3. java 内存模型简述 java 类加载机制?
  4. 类加载器双亲委派模型机制?
  5. 什么是类加载器,类加载器有哪些?
  6. 简述 java 内存分配与回收策率以及 Minor GC 和Major GC

一、简述 java 垃圾回收机制?
在 java 中,程序员是不需要显示的去释放一个对象的内存的,而是由虚拟机自行执行。在JVM 中,有一个垃圾回收线程,它是低优先级的,在正常情况下是不会执行的,只有在虚拟机空闲或者当前堆内存不足时,才会触发执行,扫面那些没有被任何引用的对象,并将它们添加到要回收的集合中,进行回收。


二、java 中垃圾收集的方法有哪些?

1. 标记-清除:

这是垃圾收集算法中最基础的,根据名字就可以知道,它的思想就是标记哪些要被
回收的对象,然后统一回收。这种方法很简单,但是会有两个主要问题:1.效率不
高,标记和清除的效率都很低;2.会产生大量不连续的内存碎片,导致以后程序在
分配较大的对象时,由于没有充足的连续内存而提前触发一次 GC 动作。

2. 复制算法:

为了解决效率问题,复制算法将可用内存按容量划分为相等的两部分,然后每次只
使用其中的一块,当一块内存用完时,就将还存活的对象复制到第二块内存上,然
后一次性清楚完第一块内存,再将第二块上的对象复制到第一块。但是这种方式,
内存的代价太高,每次基本上都要浪费一般的内存。
于是将该算法进行了改进,内存区域不再是按照 1:1 去划分,而是将内存划分为
8:1:1 三部分,较大那份内存交 Eden 区,其余是两块较小的内存区叫 Survior 区。
每次都会优先使用 Eden 区,若 Eden 区满,就将对象复制到第二块内存区上,然
后清除 Eden 区,如果此时存活的对象太多,以至于 Survivor 不够时,会将这些对
象通过分配担保机制复制到老年代中。(java 堆又分为新生代和老年代)

3. 标记-整理

该算法主要是为了解决标记-清除,产生大量内存碎片的问题;当对象存活率较高
时,也解决了复制算法的效率问题。它的不同之处就是在清除对象的时候现将可回
收对象移动到一端,然后清除掉端边界以外的对象,这样就不会产生内存碎片了。

4. 分代收集

现在的虚拟机垃圾收集大多采用这种方式,它根据对象的生存周期,将堆分为新生
代和老年代。在新生代中,由于对象生存期短,每次回收都会有大量对象死去,那
么这时就采用复制算法。老年代里的对象存活率较高,没有额外的空间进行分配担
保,所以可以使用标记-整理 或者 标记-清除。


三、java 内存模型

java 内存模型(JMM)是线程间通信的控制机制.JMM 定义了主内存和线程之间抽象关系。
线程之间的共享变量存储在主内存(main memory)中,每个线程都有一个私有的本地
内存(local memory),本地内存中存储了该线程以读/写共享变量的副本。本地内存是
JMM 的一个抽象概念,并不真实存在。它涵盖了缓存,写缓冲区,寄存器以及其他的硬
件和编译器优化。Java 内存模型的抽象示意图如下:
从上图来看,线程 A 与线程 B 之间如要通信的话,必须要经历下面 2 个步骤:

  1. 首先,线程 A 把本地内存 A 中更新过的共享变量刷新到主内存中去。
  2. 然后,线程 B 到主内存中去读取线程 A 之前已更新过的共享变量。

四、简述 java 类加载机制?

虚拟机把描述类的数据从 Class 文件加载到内存,并对数据进行校验,解析和初始化,最
终形成可以被虚拟机直接使用的 java 类型。


五、类加载器双亲委派模型机制?

当一个类收到了类加载请求时,不会自己先去加载这个类,而是将其委派给父类,由父类
去加载,如果此时父类不能加载,反馈给子类,由子类去完成类的加载。


六、什么是类加载器,类加载器有哪些?

实现通过类的权限定名获取该类的二进制字节流的代码块叫做类加载器。
主要有一下四种类加载器:

  1. 启动类加载器(Bootstrap ClassLoader)用来加载 java 核心类库,无法被 java 程序直接
    引用。
  2. 扩展类加载器(extensions class loader):它用来加载 Java 的扩展库。Java 虚拟机的
    实现会提供一个扩展库目录。该类加载器在此目录里面查找并加载 Java 类。
  3. 系统类加载器(system class loader):它根据 Java 应用的类路径(CLASSPATH)来加载 Java 类。一般来说,Java 应用的类都是由它来完成加载的。可以通过ClassLoader.getSystemClassLoader()来获取它。
  4. 用户自定义类加载器,通过继承 java.lang.ClassLoader 类的方式实现。

七、简述 java 内存分配与回收策率以及 Minor GC 和Major GC

  1. 对象优先在堆的 Eden 区分配。
  2. 大对象直接进入老年代.
  3. 长期存活的对象将直接进入老年代.
    当 Eden 区没有足够的空间进行分配时,虚拟机会执行一次 Minor GC.Minor Gc 通
    常发生在新生代的 Eden 区,在这个区的对象生存期短,往往发生 Gc 的频率较高,
    回收速度比较快;Full Gc/Major GC 发生在老年代,一般情况下,触发老年代 GC
    的时候不会触发 Minor GC,但是通过配置,可以在 Full GC 之前进行一次 Minor
    GC 这样可以加快老年代的回收速度。

总结

  1. 简述 java 垃圾回收机制?
  2. java 中垃圾收集的方法有哪些?
  3. java 内存模型简述 java 类加载机制?
  4. 类加载器双亲委派模型机制?
  5. 什么是类加载器,类加载器有哪些?
  6. 简述 java 内存分配与回收策率以及 Minor GC 和Major GC

你可能感兴趣的:(面试,jvm)