面试 JVM 八股文十问十答第七期

面试 JVM 八股文十问十答第七期

作者:程序员小白条个人博客

相信看了本文后,对你的面试是有一定帮助的!关注专栏后就能收到持续更新!

⭐点赞⭐收藏⭐不迷路!⭐

1)逃逸分析有了解过吗?

逃逸分析是一种用于确定对象生命周期的优化技术。它通过分析对象在代码中的作用域和生命周期来判断对象是否逃逸出了方法的作用范围。如果对象没有逃逸,那么编译器可以进行一些优化,比如栈上分配对象,减少对堆的访问,提高程序的性能。逃逸分析在Java等编程语言的编译器中广泛应用,可以帮助编译器做出更好的优化决策。

2)指令重排有听过吗?

指令重排是指编译器或处理器在不改变程序执行结果的前提下,对指令的执行顺序进行重新排序的优化技术。指令重排可以提高程序的执行效率,减少处理器的空闲时间,但需要确保不会改变程序的语义。在多线程编程中,指令重排可能会导致内存可见性问题,因此需要通过内存屏障等机制来保证程序的正确性。

3)说说强、软、弱、虚引用?

强引用(Strong Reference)是Java中最常见的引用类型,如果一个对象被强引用所引用,那么它就不会被垃圾回收器回收,直到该引用被显式地释放。

软引用(Soft Reference)是一种比强引用弱一些的引用类型。当系统内存不足时,垃圾回收器可能会回收软引用指向的对象,但会尽量避免回收,只有在内存不足时才会进行回收。

弱引用(Weak Reference)是一种比软引用更弱的引用类型。垃圾回收器在进行垃圾回收时,会立即回收弱引用指向的对象,不考虑系统内存的情况。

虚引用(Phantom Reference)是一种最弱的引用类型。虚引用的作用是在对象被回收时收到一个系统通知,可以用于在对象被回收时执行一些特定的操作,比如清理资源或发送通知。虚引用主要用于跟踪对象被回收的状态,而不是直接获取对象的引用。

4)说说 Java 常见的垃圾收集器?

Java 中常见的垃圾收集器包括:

  • Serial收集器:Serial收集器是最基本、最古老的收集器之一,它使用单线程进行垃圾收集,在新生代使用复制算法,在老年代使用标记-整理算法。
  • Parallel收集器:Parallel收集器也称为吞吐量收集器,它使用多线程进行垃圾收集,以提高垃圾收集的吞吐量。在新生代使用复制算法,在老年代使用标记-整理算法。
  • CMS收集器(Concurrent Mark-Sweep):CMS收集器是一种以最短停顿时间为目标的收集器,它使用多线程进行垃圾收集,在新生代使用复制算法,在老年代使用标记-清除算法。
  • G1收集器(Garbage-First):G1收集器是一种面向服务端应用的垃圾收集器,它将堆划分为多个大小相等的区域,通过优先收集垃圾最多的区域来降低停顿时间。

5)垃圾回收,如何判断对象是否是垃圾?不同方式有什么区别?

判断对象是否是垃圾的方式主要有以下几种:

  • 引用计数法:通过计算对象的引用数量来判断对象是否可达。当对象的引用数量为0时,说明对象不再被引用,可以被回收。
  • 可达性分析法:通过判断对象是否能够被一系列“根对象”(如栈中的引用、静态变量等)直接或间接访问到来判断对象是否可达。如果对象不可达,则被认为是垃圾。

这两种方式的区别在于判断对象是否可达的方式不同。引用计数法简单直观,但无法处理循环引用的情况,而可达性分析法可以处理循环引用,并且更准确。

6)为什么 Java 要分老年代和新生代?

Java 将堆内存划分为新生代和老年代的主要原因是为了优化垃圾收集的效率和减少垃圾回收的停顿时间。

新生代主要存放新创建的对象,对象的生命周期较短。因此,采用复制算法来进行垃圾回收,即将新生代划分为 Eden 区和两个 Survivor 区,通过复制存活对象的方式来进行垃圾收集,减少了内存碎片的产生,同时也可以快速地进行垃圾回收。

老年代主要存放长时间存活的对象,对象的生命周期较长。采用标记-整理或标记-清除算法进行垃圾回收,因为老年代的对象较多,采用复制算法会导致效率低下。通过将新生代和老年代分开管理,可以根据对象的生命周期采用不同的垃圾收集算法,从而提高了垃圾收集的效率和系统的性能。

7)为什么 Java8 移除了永久代,加了元空间?

Java 8 移除了永久代(PermGen)主要是为了解决永久代的一些问题。永久代是一种特殊的堆内存区域,用于存放类的元数据、常量池等信息。然而,永久代有一些缺点,比如固定大小难以调整、垃圾收集效率低下、容易出现内存溢出等。为了解决这些问题,Java 8 引入了元空间(Metaspace)。元空间使用本地内存来存放类的元数据,不再受到堆大小的限制,可以动态地调整大小,同时也减少了垃圾收集的负担,提高了系统的稳定性和性能。

8)为什么新生代又要分 s1、s2 和 eden?

新生代之所以要分为 Eden 区和两个 Survivor 区(通常称为 S0 和 S1),主要是为了实现复制算法。新创建的对象首先会被分配到 Eden 区,当 Eden 区满时,剩余的存活对象会被复制到其中一个 Survivor 区,然后清空 Eden 区。当这个 Survivor 区也满时,存活的对象会被复制到另一个 Survivor 区中,然后清空当前 Survivor 区。这样交替使用的方式可以减少复制对象的次数,提高了垃圾收集的效率。

9)你知道有哪些垃圾回收算法?

常见的垃圾回收算法包括:

  • 标记-清除(Mark and Sweep):首先标记出所有需要回收的对象,然后清除掉所有未被标记的对象。该算法会导致内存碎片化,并且效率较低。
  • 标记-整理(Mark and Compact):首先标记出所有需要回收的对象,然后将存活的对象向一端移动,然后清理掉边界以外的内存。该算法解决了内存碎片化的问题,但移动对象会导致一定的性能开销。
  • 复制(Copying):将存活的对象复制到另一块空闲的内存区域中,然后清理掉原来的内存区域。这种算法简单高效,但会浪费一半的内存空间。
  • 分代收集(Generational Collection):将堆内存划分为新生代和老年代,针对不同代采用不同的垃圾回收算法。新生代一般采用复制算法,老年代一般采用标记-整理或标记-清除算法。

10)三色标记有听过吗?

三色标记是一种用于增量式垃圾收集的算法。它将对象分为三种状态:白色、灰色和黑色。初始时,所有对象都被标记为白色,表示未访问过。然后从根节点开始遍历对象图,将访问到的对象标记为灰色,表示待访问。当访问完一个对象的所有引用后,将其标记为黑色,表示已访问过。通过不断重复这个过程,直到所有可达对象都被标记为黑色,未标记的对象就是可以回收的垃圾。三色标记算法可以在不停止应用程序的情况下进行垃圾回收,降低了垃圾回收的停顿时间,提高了系统的响应性。

开源项目地址:https://gitee.com/falle22222n-leaves/vue_-book-manage-system

前后端总计已经 1300+ Star,2W+ 访问!

⭐点赞⭐收藏⭐不迷路!⭐

相关推荐

  1. 面试 JVM 八股文

    2024-05-16 10:40:16       40 阅读
  2. 面试 JVM 八股文

    2024-05-16 10:40:16       42 阅读
  3. 面试 JVM 八股文

    2024-05-16 10:40:16       49 阅读
  4. 面试 JVM 八股文

    2024-05-16 10:40:16       45 阅读
  5. 面试 JVM 八股文

    2024-05-16 10:40:16       35 阅读
  6. 面试前端八股文

    2024-05-16 10:40:16       32 阅读
  7. 面试前端八股文

    2024-05-16 10:40:16       29 阅读
  8. 面试前端八股文

    2024-05-16 10:40:16       32 阅读
  9. 面试前端八股文

    2024-05-16 10:40:16       37 阅读
  10. 面试 Redis 八股文

    2024-05-16 10:40:16       33 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-16 10:40:16       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-16 10:40:16       106 阅读
  3. 在Django里面运行非项目文件

    2024-05-16 10:40:16       87 阅读
  4. Python语言-面向对象

    2024-05-16 10:40:16       96 阅读

热门阅读

  1. 12、24年--信息系统治理——IT治理

    2024-05-16 10:40:16       25 阅读
  2. verilog testbench-产生时钟复位

    2024-05-16 10:40:16       30 阅读
  3. 用ffmpeg和EasyDARWIN实现推流

    2024-05-16 10:40:16       34 阅读
  4. 【Linux深度学习5.15(堡垒机)】

    2024-05-16 10:40:16       32 阅读
  5. leetcode-42. 接雨水(双指针,前缀)

    2024-05-16 10:40:16       25 阅读
  6. 验证torch.nn.Conv2d

    2024-05-16 10:40:16       27 阅读