java面试题-JVM类加载机制

news2024/9/27 5:45:20
  1. 类加载的生命周期?

1. 加载阶段(Loading)

在Java程序中,当需要使用某个类时,JVM会使用类加载器来查找并加载该类文件。类加载器会首先从文件系统或网络中查找相应的 .class 文件,读取类的二进制数据,并将其存储在JVM的内存中。在这个过程中,JVM会为该类创建一个对应的Java类对象。这个Java类对象包含了该类的类名、父类名、接口名、访问修饰符、成员变量和成员方法等信息。

2. 链接阶段(Linking)

在类加载完成后,JVM会对该类进行链接。链接分为三个步骤:验证、准备和解析。

  • 验证阶段:在验证阶段,JVM会对类文件的格式、依赖关系、语义等进行检查。如果验证失败,JVM会抛出相应的异常。

  • 准备阶段:在准备阶段,JVM会为类的静态成员分配内存空间,并设置默认初始值。在Java程序中,静态变量的默认初始值是0或null,而不是程序员在代码中定义的初始值。如果类的静态成员是常量,则在编译期间就已经分配了内存空间,并设置了正确的初始值。因此,在准备阶段,常量并不需要分配内存空间。

  • 解析阶段:在解析阶段,JVM会将类中的符号引用转换为直接引用。在Java程序中,类中的方法调用、变量引用等都是通过符号引用实现的。而在JVM中,这些符号引用需要被解析为直接引用,以便JVM能够正确地执行程序。在解析阶段,JVM会将符号引用转换为直接引用,并生成相应的调用指令。

3. 初始化阶段(Initialization)

在初始化阶段,JVM会为类的静态成员赋予正确的值。在Java程序中,静态变量和静态代码块的初始化操作都是在初始化阶段完成的。当JVM完成初始化操作后,Java程序才能正常地使用该类。需要注意的是,初始化操作只会执行一次。如果类已经被初始化过,JVM不会再次执行初始化操作。

总体来说,Java类加载器的生命周期可以分为加载、链接和初始化三个阶段。在这三个阶段中,JVM会对类文件进行验证、解析、分配内存空间、设置初始值等操作,以确保Java程序的正确执行。

2.类加载器的层次?

在Java中,类加载器的层次结构可以分为以下三个层次:

  1. 启动类加载器(Bootstrap ClassLoader)

启动类加载器是JVM内置的类加载器,它负责加载JRE核心库中的类,包括 rt.jarresources.jar 中的类。它是Java类加载器中唯一没有父类加载器的加载器,由JVM自身实现。在Java程序中,我们无法直接获取到启动类加载器的引用。

  1. 扩展类加载器(Extension ClassLoader)

扩展类加载器是用来加载JRE扩展目录中的类,通常位于 jre/lib/ext 目录下。它的父类加载器是启动类加载器。扩展类加载器的实现由JVM提供,它可以通过 java.lang.ClassLoader.getSystemClassLoader().getParent() 获取到其父类加载器。

  1. 应用程序类加载器(Application ClassLoader)

应用程序类加载器(也称为系统类加载器)是用来加载应用程序类路径上的类,通常位于 classpath 下的类和库。它的父类加载器是扩展类加载器。应用程序类加载器的实现也由JVM提供,可以通过 java.lang.ClassLoader.getSystemClassLoader() 获取到其引用。

  1. 自定义类加载器

除了这三个基本的类加载器,Java还支持自定义类加载器。自定义类加载器可以继承自 java.lang.ClassLoader 类,通过重写其中的 findClass() 方法和 loadClass() 方法实现类的加载。这样可以实现特定的类加载需求,比如从网络或数据库中动态加载类。在实现自定义类加载器时,需要注意遵循双亲委派模型的原则,保证类的唯一性和正确性。

3.Class.forName()和ClassLoader.loadClass()区别?

在Java中,Class.forName()ClassLoader.loadClass() 都可以用来加载类,但二者有一些区别。

  1. 类加载器的区别

Class.forName() 方法使用的是当前线程的类加载器(即调用 Class.forName() 方法的类的类加载器)来加载指定的类。如果没有指定类加载器,那么默认使用的是系统类加载器。如果这个类还没有被加载,那么该方法将加载并初始化这个类。如果这个类已经被加载,那么该方法将返回这个类的 Class 对象。此外,Class.forName() 还可以指定是否要初始化这个类。

ClassLoader.loadClass() 方法是一个实例方法,需要通过类加载器的实例来调用。它只是简单地加载指定的类,但不会对其进行初始化操作。如果想对这个类进行初始化,需要调用 Class.forName()Class.newInstance() 方法。

  1. 返回值的不同

Class.forName() 方法返回一个 Class 对象,该对象包含了类的所有信息,包括类的名称、方法、属性等。

ClassLoader.loadClass() 方法只是简单地加载类,返回的是一个 Class<?> 类型的对象,只包含类的类型信息。如果需要使用该类的实例对象,还需要通过反射或者其他方式来获取。

  1. 加载类的方式的不同

Class.forName() 方法会在加载类的同时对其进行初始化操作,这意味着会执行静态代码块和初始化类变量等操作。

ClassLoader.loadClass() 方法只会简单地加载类,不会执行任何初始化操作。如果需要对类进行初始化,需要手动调用 Class.forName() 或者 Class.newInstance() 方法。

需要注意的是,Class.forName()ClassLoader.loadClass() 在加载类时都会遵循双亲委派模型。即当一个类加载器需要加载一个类时,它首先委派给其父类加载器去加载,如果父类加载器无法加载该类,再由该类加载器自己尝试加载。这样可以保证类的唯一性和正确性。

4.JVM有哪些类加载机制?

Java虚拟机(JVM)的类加载机制主要包括以下几种:

  1. 全盘负责机制(Bootstrap ClassLoader)

Java虚拟机内置的启动类加载器(Bootstrap ClassLoader)会负责加载Java平台核心库中的类,包括 java.langjava.util 等类。由于这些类都是由JVM实现的,因此在加载这些类时,不需要考虑类的版本和安全性问题。

  1. 父类委托机制(Parent Delegation Model)

父类委托机制是Java类加载机制中的核心机制。当一个类需要被加载时,它会先委托给父类加载器去尝试加载。如果父类加载器无法加载这个类,那么它才会由当前类加载器自己去加载。这个过程会一直持续到最顶层的启动类加载器为止,如果仍然无法加载该类,那么就会抛出 ClassNotFoundException 异常。

父类委托机制可以保证Java虚拟机中的类不会出现重名的情况,而且可以保证Java类库的安全性。

  1. 缓存机制(Cache Mechanism)

缓存机制是指,在类加载器加载一个类之后,会将这个类的Class对象缓存起来,下次再加载这个类时,就可以直接从缓存中取出,避免重复加载。

缓存机制可以提高类的加载效率,避免重复加载类的字节码,但同时也可能会导致内存泄漏问题。

  1. 双亲委派机制(Double-Delegation Mechanism)

双亲委派机制是一种更加严格的父类委托机制。在双亲委派机制中,除了顶层的启动类加载器,每个类加载器都有且只有一个父类加载器,并且会优先委托给父类加载器去加载类。如果父类加载器无法加载该类,才会尝试自己去加载。这样可以保证类的唯一性和正确性,避免了重复加载和安全问题。

  • 当AppClassLoader加载一个class时,它首先不会自己去尝试加载这个类,而是把类加载请求委派给父类加载器ExtClassLoader去完成。

  • 当ExtClassLoader加载一个class时,它首先也不会自己去尝试加载这个类,而是把类加载请求委派给BootStrapClassLoader去完成。

  • 如果BootStrapClassLoader加载失败(例如在$JAVA_HOME/jre/lib里未查找到该class),会使用ExtClassLoader来尝试加载;

  • 若ExtClassLoader也加载失败,则会使用AppClassLoader来加载,如果AppClassLoader也加载失败,则会报出异常ClassNotFoundException

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

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

相关文章

【JDK8新特性之方法引用-案例实操】

一.JDK8新特性之方法引用-案例实操 之前我们学习了Stream流以及Lambda表达式相关的内容&#xff0c;如果想看的同学可以看一下之前的文章&#xff0c;接下来我们就来学习让Lambda表达式更加简洁的方法引用。 二. 什么是方法引用&#xff1f;为什么要使用方法引用&#xff1f; …

Leetcode Solutions - Part 1

回溯: 字符串的排列 回溯&#xff1a;78. 子集 给你一个整数数组 nums &#xff0c;数组中的元素 互不相同 。返回该数组所有可能的子集&#xff08;幂集&#xff09;。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 示例 1&#xff1a; 输入&#xff1a;nums …

【Java】让我们对多态有深入的了解(九)

目录 &#xff08;1&#xff09;接口的基本介绍​编辑 &#xff08;2&#xff09;接口的注意事项和细节 1.接口不能被实例化 2.接口中所有方法是public方法&#xff0c;接口中的抽象方法&#xff0c;可以不用abstract修饰 3.一个普通类实现接口&#xff0c;必须将接口所有…

ARMv8 architecture里的Memory aborts

在AArch64 Virtual Memory System Architecture中&#xff0c;有以下几种机制会导致PE在访问memory失败时产生exceptions。 Debug exception: An exception caused by the debug configuration.Alignment fault: An Alignment fault is generated if the address used for a m…

【YSYY】DSPE-PEG-cRGD,磷脂-聚乙二醇-靶向穿膜肽,靶向功能材料

靶向穿膜肽RGD环肽&#xff0c;磷脂-聚乙二醇-cRGD中的cRGD是五元环肽。 DSPE&#xff08;1,2-二硬脂酰-sn-甘油-3-磷酸乙醇胺&#xff09;是一种饱和的18碳磷脂&#xff0c;常用于脂质体的合成。聚乙二醇&#xff08;PEG&#xff09;偶联DSPE具有亲水性。聚乙二醇能增强溶解性…

一文2000字手把手教你自动化测试Selenium+pytest+数据驱动

主流自动化框架 selenium &#xff1a;web端自动化框架 &#xff0c;&#xff08;行业里面最核心的框架&#xff09; appium &#xff1a;手机app端框架 requests &#xff1a;接口测试 selenium 工具类封装 selenium提供了很多方法供我们去完成网页元素的操作&#xff0c; …

1.创建Springboot项目

一&#xff1a;进入https://start.spring.io/&#xff0c;如下是相关步骤&#xff1a;地址https://start.spring.io/maven 方式springboot版本项目名称jar方式点击创建二&#xff1a;点击&#xff08;generate&#xff09;生产自动下载1.IDEA 直接打开2.启动成功SpringdiApplic…

【计算机网络】TCP底层设计交互原理

文章目录1.TCP底层三次握手详细流程2.TCP洪水攻击介绍和ss命令浅析3.Linux服务器TCP洪水攻击入侵案例4.TCP洪水攻击结果分析和解决方案5.TCP底层四次挥手详细流程1.TCP底层三次握手详细流程 TCP的可靠性传输机制&#xff1a;TCP三次我手的流程 一次握手&#xff1a;客户端发送一…

Java中抽象类有什么用

抽象类是用来捕捉子类的通用特性的&#xff0c;是被用来创建继承层级里子类的模板。现实中有些父类中的方法确实没有必要写&#xff0c;因为各个子类中的这个方法肯定会有不同&#xff1b;而写成抽象类&#xff0c;这样看代码时&#xff0c;就知道这是抽象方法&#xff0c;而知…

39-Golang中的接口

Golang中的接口基本介绍基本语法注意事项和细节案例实现对Hero结构体切片的排序&#xff1a;sort.Sort(data Interface)实现接口和继承之间的比较区别基本介绍 interface类型可以定义一组方法&#xff0c;但是这些不需要实现。并且interface不能包含任何变量。到某个自定义类型…

【编程入门】应用市场(NodeJS版)

背景 前面已输出多个系列&#xff1a; 《十余种编程语言做个计算器》 《十余种编程语言写2048小游戏》 《17种编程语言10种排序算法》 《十余种编程语言写博客系统》 《十余种编程语言写云笔记》 《N种编程语言做个记事本》 目标 为编程初学者打造入门学习项目&#xff0c;使…

JUC-Synchronized相关内容

设计同步器的意义多线程编程中&#xff0c;有可能会出现多个线程同时访问同一个共享、可变资源的情况&#xff0c;这个资源我们称之其为临界资源&#xff1b;这种资源可能是&#xff1a;对象、变量、文件等。共享&#xff1a;资源可以由多个线程同时访问可变&#xff1a;资源可…

25 openEuler管理网络-使用nmcli命令配置ip

文章目录25 openEuler管理网络-使用nmcli命令配置ip25.1 nmcli介绍25.2 设备管理25.2.1 连接到设备25.2.2 断开设备连接25.3 设置网络连接25.3.1 配置动态IP连接25.3.1.1 配置IP25.3.1.2 激活连接并检查状态25.3.2 配置静态IP连接25.3.2.1 配置IP25.3.2.2 激活连接并检查状态25…

Mr. Cappuccino的第44杯咖啡——Kubernetes之Service

Kubernetes之ServiceService的概念Service的类型Service演示案例环境准备ClusterIP&#xff08;集群内部访问&#xff09;IptablesIPVSEndpointNodePort&#xff08;对外暴露应用&#xff09;LoadBalancer&#xff08;对外暴露应用&#xff0c;适用于公有云&#xff09;Ingress…

3.抽象工厂模式

与工厂模式对比 工厂模式 工厂模式是类创建模式。在工厂模式中&#xff0c;只需要生产同一种产品&#xff0c;只不过是生产厂家不同。 所以产品类的设计&#xff1a; 抽象的产品类Product具体的产品类Product_A&#xff0c;Product_B, Product_C, Product_D…… 工厂的设计…

详解Android 13种 Drawable的使用方法

前言关于自定义View&#xff0c;相信大家都已经很熟悉了。今天&#xff0c;我想分享一下关于自定义View中的一部分&#xff0c;就是自定义Drawable。Drawable 是可绘制对象的一个抽象类&#xff0c;相对比View来说&#xff0c;它更加的纯粹&#xff0c;只用来处理绘制的相关工作…

用Python+ChatGPT批量生成论文概述

用PythonChatGPT批量生成论文概述 做算法研究离不开阅读大量论文。从海量论文中找到需要的论文往往耗费算法团队不少的精力。 ChatGPT官方例子中有一个“TL;DR”摘要生成&#xff0c;非常适合生成论文摘要。 于是我用pythonGPT-3 API开发了一个工具&#xff0c;可以直接从arx…

基于Android校园失物招领的设计与实现

需求信息&#xff1a; 客户端&#xff1a; 1&#xff1a;登录注册&#xff1a;用户可以通过自己的信息进行账号的注册 2&#xff1a;查看信息&#xff1a;用户可以查看失物和拾物信息&#xff0c;以及对信息进行点赞和评论 3&#xff1a;发布拾物信息&#xff1a;用户可以发布自…

连阿迪达斯都卖不动了!是国潮太卷,还是消费者对品牌祛魅了?

据权威报告&#xff0c;2022年&#xff0c;阿迪达斯业绩不佳&#xff0c;尤其是大中华区表现疲软。就在昨晚&#xff0c;阿迪在业绩指引中称“2023年营运亏损可能高达7亿欧元”&#xff0c;其美国存凭证&#xff08;ADR&#xff09;价格暴跌近9%。值得注意的是&#xff0c;这已…

2分钟告诉你怎么成为一名黑客?零基础入门

在很久很久以前&#xff08;别问我有多久&#xff0c;不要在意这些细节&#xff09;&#xff0c;“ 黑客”指的是 喜爱钻研技术、精通计算机技术的程序员。后来有些黑客写了些能破坏程序或者系统正常运行的代码&#xff0c;又用搞了些破坏&#xff0c;于是这些黑客有了新的称呼…