JVM工作原理与实战(四十三):JVM常见面试题目

专栏导航

JVM工作原理与实战

RabbitMQ入门指南

从零开始了解大数据


目录

专栏导航

前言

一、JVM常见面试题目

1.什么是类加载器,有哪些常见的类加载器?

2.什么是双亲委派机制,以及如何打破双亲委派机制?

3.如何判断堆上的对象没有被引用?

4.JVM 中都有哪些引用类型?

5.ThreadLocal中为什么要使用弱引用?

6.有哪些常见的垃圾回收算法?

总结


前言

JVM作为Java程序的运行环境,其负责解释和执行字节码,管理内存,确保安全,支持多线程和提供性能监控工具,以及确保程序的跨平台运行。本文主要介绍了JVM常见面试题目等内容。


一、JVM常见面试题目

关于以下问题的详尽解析,请查阅对应专栏所发布的专题文章:

JVM工作原理与实战_橘子-青衫的博客-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/jiangyq_/category_12539794.html

1.什么是类加载器,有哪些常见的类加载器?

类加载器是Java虚拟机(JVM)的一部分,它的主要任务是在类的加载过程中,从文件系统、网络或其他来源动态加载类的字节码,并将其转换为可以在JVM中运行的类。在JDK 9及之后的版本中,类加载器完全由Java实现。

常见的类加载器有以下几种:

  • 启动类加载器(Bootstrap ClassLoader):这是JVM的顶层加载类,主要负责加载核心类库,如java.lang、java.util等。这些类库是JVM启动时必须加载的。
  • 平台类加载器(Platform ClassLoader):在JDK 9及之后的版本中,原本的扩展类加载器(Extension ClassLoader)被重命名为平台类加载器。它主要负责加载平台扩展类库,这些类库通常位于$JAVA_HOME/lib/ext目录下。
  • 应用程序类加载器(Application ClassLoader):这个类加载器负责加载应用程序classpath下的类文件。在大多数情况下,它是开发人员与类加载器交互的入口。
  • 自定义类加载器:除了上述三种默认的类加载器,Java还允许开发者根据需要自定义类加载器。自定义类加载器通常通过继承java.lang.ClassLoader类并重写其findClass方法来实现。这样,开发者可以根据自己的需求,从特定的位置(如数据库、网络等)加载类。

参考回答:类加载器是JVM的一部分,负责加载类的字节码到内存中。常见的类加载器有启动类加载器、平台类加载器(在JDK 9+中替代了扩展类加载器)、应用程序类加载器和自定义类加载器。

2.什么是双亲委派机制,以及如何打破双亲委派机制?

双亲委派模型是Java类加载机制中的一个核心概念,它确保了类加载的安全性和一致性。在双亲委派模型中,当一个类加载器收到类加载请求时,它不会自己首先尝试加载,而是将这个请求委派给它的父类加载器去完成。只有当父类加载器无法完成加载请求时,子类加载器才会尝试自己加载。

双亲委派模型的主要作用有两点:首先,它避免了类的重复加载,每个类只会被加载一次。其次,它确保了Java核心API的稳定性,因为自定义的类加载器无法加载Java核心类,从而避免了可能的代码冲突和安全风险。

在Java中,可以通过继承ClassLoader并重写其loadClass方法来创建自定义类加载器。通过这种方式,可以打破双亲委派机制,实现类的隔离。例如,在Tomcat中,每个Web应用都有自己的类加载器,从而实现了应用之间的类隔离。当两个Web应用中有相同限定名的类时,如Servlet类,Tomcat通过自定义类加载器保证它们是不同的类。

参考回答:双亲委派模型是Java类加载机制的核心组成部分,它要求一个类加载器在尝试加载一个类之前,先将其加载请求委派给其父类加载器。通过这种方式,从顶层启动类加载器开始,逐级向下进行类加载,确保了核心类库的稳定性与安全性,同时避免了类的重复加载。要打破双亲委派机制,常见的做法是实现自定义类加载器,并重写defineClass方法。

3.如何判断堆上的对象没有被引用?

在Java中,判断堆上对象是否已被垃圾回收的过程是通过可达性分析算法来完成的。这个算法将对象分为两类:垃圾回收的根对象(GC Root)和普通对象。可达性分析算法的核心思想是:如果一个对象从GC Root开始,按照引用关系向下搜索,不可达(即不存在引用链)到该对象,那么该对象就被认为是不可达的,即可以被垃圾回收。最常见的是,GC Root对象会引用栈上的局部变量和静态变量,如果这些引用被断开,那么对应的对象就会变得不可达,从而可能被垃圾回收。与引用计数法相比,可达性分析算法能够更准确地判断对象的可回收性,因为它能够处理循环引用的情况。

引用计数法会为每个对象维护一个引用计数器,每当对象被引用时计数器加1,取消引用时减1。然而,当存在循环引用时,即使对象之间不再需要相互引用,引用计数器也不会归零,从而导致内存泄漏。因此,Java选择了可达性分析算法来管理内存,以避免这类问题。

参考回答:在Java中,通过可达性分析算法判断堆上对象是否可回收。该算法从GC Root开始,检查对象是否可达。若对象不可达,则可能被回收。与引用计数法不同,可达性分析能处理循环引用问题,避免了内存泄漏。因此,Java采用可达性分析算法来管理内存。

4.JVM 中都有哪些引用类型?

在JVM中,存在多种引用类型,每种类型都有其特定的用途和特性。

  • 强引用:JVM中最常见的引用类型,它表示对象被局部变量、静态变量等GC Root所关联。只要强引用存在,垃圾回收器就不会回收该对象。
  • 软引用:一种相对较弱的引用关系。当系统内存足够时,软引用对象不会被回收;但在内存不足时,软引用对象会被回收,以释放内存空间。软引用在缓存框架中特别有用,因为它们允许系统在需要时释放不常使用的数据。
  • 弱引用:与软引用类似,但弱引用的对象在垃圾回收时,无论内存是否充足,都会被回收。弱引用主要在ThreadLocal中使用,以确保线程局部变量的及时清理。
  • 虚引用(也被称为幽灵引用或幻影引用):不会直接关联到对象。它的唯一用途是能在对象被垃圾回收时接收到通知。虚引用主要用于跟踪对象被垃圾回收的活动,例如,在直接内存管理中,虚引用可以用来监控和回收不再使用的内存对象。
  • 终结器引用:涉及对象的finalize方法。当对象被垃圾回收器标记为需要回收时,终结器引用会将其放入Finalizer类的引用队列中。稍后,由FinalizerThread线程从队列中取出对象,并执行其finalize方法。然而,需要注意的是,依赖finalize方法进行资源清理是不推荐的,因为它不是确定性的,并且可能导致性能问题。

参考回答:在JVM中,有四种主要引用类型:强引用、软引用、弱引用和虚引用。强引用是最常见的,它确保对象不被垃圾回收。软引用和弱引用用于内存管理,软引用在内存不足时回收对象,而弱引用则无论内存是否充足都会回收对象。虚引用主要用于对象被回收时的通知。此外,还有终结器引用,它关联对象并执行finalize方法,但现代Java开发中较少使用。

5.ThreadLocal中为什么要使用弱引用?

在ThreadLocal中使用弱引用的主要目的是为了解决内存泄漏问题。通常,ThreadLocal实例作为静态成员变量存在,其生命周期与应用程序的运行时长相同。如果ThreadLocal中存储的对象使用强引用,那么这些对象将一直存在,直到ThreadLocal实例被显式地回收,这可能导致内存泄漏。

通过使用弱引用,当没有其他强引用指向ThreadLocal中的对象时,这些对象可以被垃圾回收器回收,从而减少了内存泄漏的风险。然而,仅仅使用弱引用并不足以完全解决对象回收的问题。因为ThreadLocal内部使用Entry对象来存储值,这些Entry对象本身持有对值的强引用,这意味着即使值对象被弱引用,Entry对象仍然阻止其被回收。

因此,为了避免潜在的内存泄漏,最佳实践是在不再需要ThreadLocal变量时,手动调用其remove()方法来清除条目。这确保了Entry对象被移除,从而允许值对象(如果只有弱引用指向它)被垃圾回收。之后,当解除了对ThreadLocal实例的所有强引用时,该实例本身也可以被回收,从而彻底释放了与其关联的资源。 

参考回答:在ThreadLocal中使用弱引用是为了避免内存泄漏。弱引用允许对象在没有其他强引用时被垃圾回收,减少泄漏风险。但仅使用弱引用不足以完全解决回收问题,因为ThreadLocal内部的Entry对象持有强引用。因此,最佳实践是手动调用remove()来清除条目,确保对象可回收。这样,当ThreadLocal不再使用时,相关资源可以被彻底释放。

6.有哪些常见的垃圾回收算法?

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

  • 标记-清除算法(Mark-Sweep GC)

    • 优点:实现相对简单,能够处理任意对象的回收。
    • 缺点
      • 碎片化问题:由于回收过程中对象的移动和删除,可能导致内存碎片化,影响内存分配效率。
      • 分配速度慢:在清除阶段,需要遍历整个堆来寻找空闲内存,导致内存分配速度较慢。
  • 复制算法(Copying GC)

    • 优点:分配速度快,因为每次只使用一半的内存空间进行分配,没有内存碎片问题。
    • 缺点:内存使用效率低,因为每次只能使用一半的内存空间,限制了可用内存的范围。
  • 标记-整理算法(Mark-Compact GC)

    • 优点:避免了内存碎片问题,通过移动对象来整理内存,使得内存空间连续。
    • 缺点:整理阶段需要高效的算法来移动对象,否则可能导致效率不高。
  • 分代GC(Generational GC)

    • 优点:根据对象的生命周期将内存划分为不同的代,针对不同代使用不同的垃圾回收算法,提高了垃圾回收的效率和灵活性。
    • 缺点:实现复杂度较高,需要针对年轻代和老年代分别设计合适的垃圾回收策略。

在实际应用中,不同的垃圾回收器可能会结合使用上述算法,以适应不同的应用场景和性能需求。例如,在Java的HotSpot虚拟机中,就采用了分代GC的策略,其中年轻代通常使用复制算法,而老年代则使用标记-清除或标记-整理算法。

垃圾回收算法包括标记-清除(简单但可能导致内存碎片和分配速度慢)、复制(分配速度快但内存效率低)、标记-整理(避免碎片但整理可能效率不高)以及分代GC(灵活结合不同算法以满足性能需求)。


总结

JVM是Java程序的运行环境,负责字节码解释、内存管理、安全保障、多线程支持、性能监控和跨平台运行。本文主要介绍了JVM常见面试题目等内容,希望对大家有所帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/736579.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Unity性能优化篇(十) 模型优化之网格合并 Easy Mesh Combine Tool插件使用以及代码实现网格合并

把多个模型的网格合并为一个网格。可以使用自己写代码,使用Unity自带的CombineMeshes方法,也可以使用资源商店的插件,在资源商店搜Mesh Combine可以搜索到相关的插件,例如Easy Mesh Combine Tool等插件。 可大幅度减少Batches数量…

css flex 布局换行

默认使用display: flex;是不换行的,只需要加上flex-wrap: wrap;就行了,效果图 .app-center {display: flex;flex-wrap: wrap;justify-content:flex-start; } 通过上面我们发现虽然时间换行了,但是每行的边距不一样 加上这个就行了&#xff…

Jupyter Notebook使用教程——从Anaconda环境构建到Markdown、LaTex语法介绍

0. 前言 按照国际惯例,首先声明:本文只是我自己学习的理解,虽然参考了他人的宝贵见解及成果,但是内容可能存在不准确的地方。如果发现文中错误,希望批评指正,共同进步。 你是否在视频教程或说明文档或Githu…

基于java+springboot+vue实现的火车票订票系统(文末源码+Lw)294

摘要 火车票订票系统可以对火车票订票系统信息进行集中管理,可以真正避免传统管理的缺陷。火车票订票系统是一款运用软件开发技术设计实现的应用系统,在信息处理上可以达到快速的目的,不管是针对数据添加,数据维护和统计&#xf…

HAproxy反向代理与负载均衡

目录 一、HAproxy介绍 1. 概述 2. 关于4/7层负载均衡 2.1 无负载均衡 2.1.1 图示 2.1.2 说明 2.2 四层负载均衡 2.2.1 图示 2.2.2 说明 2.3 七层负载 2.3.1 图示 2.3.2 说明 3. 特性 4. HAProxy负载均衡常见策略 5. 处理模式 二、HAproxy安装 1. yum安装 2. 第…

3月11日代码随想录电话号码的字母组合

17.电话号码的字母组合 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。 示例 1: 输入:digits &q…

mysql的索引、事务、分库分表问题

1.了解MySQL的索引吗?它为什么使用Btree作为底层,而不是其他呢? 这里我们要谈的是其他数据结构的缺点,然后说说Btree的优点,也就看你对MySQL的Btree与其他数据结构熟不熟悉。 Hash (1)Hash 索引…

[HackMyVM]靶场 Espo

kali:192.168.56.104 主机发现 arp-scan -l # arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:0c:29:d2:e0:49, IPv4: 192.168.56.104 Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan) 192.168.56.1 0a:00:27:00:00:05 (Un…

openAI key 与ChatGPTPlus的关系,如何升级ChatGPTPLus

一、前言 先详细介绍一下Plus会员和Open API之间的区别: 实际上,这两者是相互独立的。举例来说,虽然您开通了Plus会员,并不意味着您就可以使用4.0版本的API。尽管这两个账户可以是同一个,但它们是完全独立的平台。 …

rocketmq学习笔记(一)安装部署

初次使用rocketmq,记录一下全流程步骤。 1、下载安装包 首先在官网,下载安装包,可也根据官方文档进行部署,但有一些细节没说明,可能会有坑,本文会尽量详细的描述每个步骤,把我踩过的坑填补上。…

后端八股笔记------Redis

Redis八股 上两种都有可能导致脏数据 所以使用两次删除缓存的技术,延时是因为数据库有主从问题需要更新,无法达到完全的强一致性,只能达到控制一致性。 一般放入缓存中的数据都是读多写少的数据 业务逻辑代码👇 写锁&#x1f4…

基础 | JVM - [指令 性能监控]

INDEX jps(jvm 进程工具)jinfo(java 配置信息工具)jstack (查看虚拟机栈信息)jmap(jvm 内存影像工具)jstat(jvm 统计信息监控工具)jvisualvm(查看…

【NR 定位】3GPP NR Positioning 5G定位标准解读(十)-增强的小区ID定位

前言 3GPP NR Positioning 5G定位标准:3GPP TS 38.305 V18 3GPP 标准网址:Directory Listing /ftp/ 【NR 定位】3GPP NR Positioning 5G定位标准解读(一)-CSDN博客 【NR 定位】3GPP NR Positioning 5G定位标准解读(…

对比才有伤害!ChatGPT 4.0 VS Claude 3,这就是ChatGPT偷懒变慢的根本原因!附解决方案

大家好,我是木易,一个持续关注AI领域的互联网技术产品经理,国内Top2本科,美国Top10 CS研究生,MBA。我坚信AI是普通人变强的“外挂”,所以创建了“AI信息Gap”这个公众号,专注于分享AI全维度知识…

每日一练:LeeCode-56、合并区间【数组+滑动窗口】

4.合并区间 LeeCode-56、合并区间 以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间&#xff0c;并返回 一个不重叠的区间数组&#xff0c;该数组需恰好覆盖输入中的所有区间 。 1 < intervals.le…

Math类 --Java学习笔记

Math 代表数学&#xff0c;是一个工具类&#xff0c;里面提供的都是对数据进行操作的一些静态方法 Math提供的常用方法

C语言分析基础排序算法——交换排序

目录 交换排序 冒泡排序 快速排序 Hoare版本快速排序 挖坑法快速排序 前后指针法快速排序 快速排序优化 快速排序非递归版 交换排序 冒泡排序 见C语言基础知识指针部分博客C语言指针-CSDN博客 快速排序 Hoare版本快速排序 Hoare版本快速排序的过程类似于二叉树前序…

安卓玩机工具推荐----MTK芯片读写分区 备份分区 恢复分区 制作线刷包 工具操作解析

安卓玩机工具推荐----高通芯片9008端口读写分区 备份分区 恢复分区 制作线刷包 工具操作解析 安卓玩机工具推荐----ADB状态读写分区 备份分区 恢复分区 查看分区号 工具操作解析 前面做了两期教程。分别解析了下ADB端口与高通9008端口备份分区一些基础的常识&#xff0c;那么…

【探索程序员职业赛道:挑战与机遇】

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老导航 檀越剑指大厂系列:全面总结 jav…

EMC技术:基础概念到应用的解读?|深圳比创达电子

电磁兼容性&#xff08;Electromagnetic Compatibility&#xff0c;简称EMC&#xff09;作为一项重要的技术领域&#xff0c;在现代电子设备中扮演着至关重要的角色。本文将从基础概念开始&#xff0c;逐步深入探讨EMC技术的原理、应用和意义。 一、EMC的基础概念 EMC是指电子…