面试连环call

  1. Java类是如何被加载到内存中的?
  2. Java类的生命周期都有哪些阶段?
  3. JVM加载的class文件都有哪些来源?
  4. JVM在加载class文件时,何时判断class文件的格式是否符合要求?

类生命周期

一个类从被加载到虚拟机内存开始,到卸载出内存为止,它的整个生命周期将会经历加载、验证、准备、解析、初始化、使用和卸载七个阶段,其中验证、准备、解析三个部分统称为连接

  • 加载、验证、准备、初始化和卸载这五个阶段的顺序是确定的,类型的加载过程必须按照这种顺序按步就班地开始,
  • 解析阶段顺序则不固定,它可以在初始化之前,而在某些情况下也可以在初始化阶段之后,这是为了支持Java语言的运行时绑定特性

类加载过程

系统加载 Class 类型的文件主要三步:加载->连接->初始化。连接过程又可分为三步:验证->准备->解析

加载

加载是类加载过程的第一个阶段,在加载阶段,虚拟机需要完成以下三件事情

  • 通过一个类的全限定名来获取其定义的二进制字节流
  • 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
  • Java堆中生成一个代表这个类的java.lang.Class对象,作为对方法区中这些数据的访问入口。

加载.class文件的方式

  • 本地文件系统中直接加载
  • 通过网络下载.class文件
  • zip,jar等归档文件中加载.class文件
  • 从专有数据库中提取.class文件
  • Java源文件动态编译为.class文件

链接

验证

确保被加载的类的正确性

验证是连接阶段的第一步,这一阶段的目的是为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。

  • 文件格式验证(Class 文件格式检查)
  • 元数据验证(字节码语义检查)
  • 字节码验证(程序语义检查)
  • 符号引用验证(类的正确性检查)

准备

为类的静态变量分配内存,并将其初始化为默认值

  • 这时候进行内存分配的仅包括类变量(static),而不包括实例变量,实例变量会在对象实例化时随着对象一块分配在Java堆中。
  • 这里所设置的初始值通常情况下是数据类型默认的零值(如00Lnullfalse等),而不是被在Java代码中被显式地赋予的值。

注意:JDK 7 之前,HotSpot 使用永久代来实现方法区的时候,类变量所使用的内存都应当在 永久的 中进行分配。 而在 JDK 7 及之后,HotSpot 已经把原本放在永久代的字符串常量池、静态变量等移动到中,这个时候类变量则会随着 Class 对象一起存放在 Java 堆中。

解析

虚拟机将常量池内的符号引用替换为直接引用的过程

解析动作主要针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用限定符 7 类符号引用进行

  1. 符号引用
  • 符号引用以一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时能够无歧义的定位到目标即可
  1. 直接引用
  • 直接指向目标的指针(比如,指向Class类型、类变量、类方法的直接引用可能是指向方法区的指针)
  • 相对偏移量(比如,指向实例变量、实例方法的直接引用都是偏移量)
  • 一个能间接定位到目标的句柄

类的初始化

当一个JVM在启动之后,其中可能包含的类非常多,是不是每个类都会被初始化呢?答案是否定的。

JVM对类的初始化是一个延迟机制,当一个类在首次使用的时候才会被初始化,在同一个运行时package下,一个Class只会被初始化一次。

《Java虚拟机规范》则是严格规定了有且只有6种情况下必须立即对类进行初始化(而加载、验证、准备自然需要在此之前开始)

  1. 通过new关键字会导致类的初始化

  2. 访问类的静态变量,包括读取和更新会导致类的初始化

  3. 访问类的静态方法,也会导致类初始化

  4. 初始化子类会导致父类被初始化

  5. 对某个类进行反射操作。会导致类被初始化

  6. 启动类,就是执行main函数所在的类会导致该类被初始化

注意:构造某个类的数组时并不会导致该类的初始化

参考内容

面试官:Java类是如何被加载到内存中的?的更多相关文章

  1. 深入浅出JVM(一):你写得.java文件是如何被加载到内存中执行的

    众所周知,.java文件需要经过编译生成.class文件才能被JVM执行. 其中,JVM是如何加载.class文件,又做了些什么呢? .class文件通过 加载->验证->准备->解 ...

  2. java动态编译类文件并加载到内存中

    如果你想在动态编译并加载了class后,能够用hibernate的数据访问接口以面向对象的方式来操作该class类,请参考这篇博文-http://www.cnblogs.com/anai/p/4270 ...

  3. java类的编译、加载和执行

    一.java类的编译流程 这里主要讲的是从java文件到class文件 下图是java类编译的详细步骤: 1.词法分析:将java源代码的字符流转变为标记(Token)的集合,Token是编译过程中的 ...

  4. 你知道 Java 类是如何被加载的吗?

    前言 最近给一个非 Java 方向的朋友讲了下双亲委派模型,朋友让我写篇文章深度研究下JVM 的 ClassLoader,我确实也好久没写 JVM 相关的文章了,有点手痒痒,涂了皮炎平也抑制不住的那种 ...

  5. Tomcat启动时加载数据到缓存---web.xml中listener加载顺序(例如顺序:1、初始化spring容器,2、初始化线程池,3、加载业务代码,将数据库中数据加载到内存中)

    最近公司要做功能迁移,原来的后台使用的Netty,现在要迁移到在uap上,也就是说所有后台的代码不能通过netty写的加载顺序加载了. 问题就来了,怎样让迁移到tomcat的代码按照原来的加载顺序进行 ...

  6. iOS图片加载到内存中占用内存情况

    我的测试结果: 图片占用内存   图片尺寸           .png文件大小 1MB              512*512          316KB 4MB              10 ...

  7. 想要配置文件生效 需要通过添加到web.xml加载到内存中

    想要配置文件生效 需要通过添加到web.xml加载到内存中

  8. java类到底是如何加载并初始化的?

    Java虚拟机如何把编译好的.class文件加载到虚拟机里面?加载之后如何初始化类?静态类变量和实例类变量的初始化过程是否相同,分别是如何初始化的呢?这篇文章就 是解决上面3个问题的. 若有不正之处, ...

  9. (转)java类到底是如何加载并初始化的?

    Java虚拟机如何把编译好的.class文件加载到虚拟机里面?加载之后如何初始化类?静态类变量和实例类变量的初始化过程是否相同,分别是如何初始化的呢?这篇文章就 是解决上面3个问题的. 若有不正之处, ...

  10. java类在何时被加载

    我们接着上一章的代码继续来了解一下java类是在什么时候加载的.在开始验证之前,我们现在IDEA做如下配置. -XX:+TraceClassLoading 监控类的加载 我们新建了一个TestCont ...

随机推荐

  1. 比Selenium更优秀的playwright介绍与未来展望

    Playwright是微软开发的,专门为满足端到端测试需求而创建的.Playwright支持包括Chromium.WebKit和Firefox在内的所有现代渲染引擎.在Windows.Linux和ma ...

  2. mogodb replication set复制集

    replication set复制集 简要命令 replication set复制集 replicattion set 多台服务器维护相同的数据副本,提高服务器的可用性. Replication se ...

  3. .NET 9 预览版:打造云原生及人工智能 AI 平台

    前言 微软发布了 .NET 9 首个预览版,分享.NET团队对 .NET 9 的初步愿景,该愿景将于今年年底在 .NET Conf 2024 上发布. 重点关注针对云原生和人工智能领域的应用程序开发以 ...

  4. 创建一个flutter项目

    启动Android  Studio,点击[Start a new Flutter project] 如果没有这项选项,请先安装Flutter插件 具体安装方法,可参考  flutter开发环境的搭建 ...

  5. PHP 中使用 ElasticSearch 的最佳实践 (下)

    引言 上一篇文章,我们使用同步的方式将数据,同步写入到 ElasticSearch 中.接下来的这篇文章,主要介绍使用 RabbitMQ 的方式,异步的将数据同步到 ElasticSearch . 部 ...

  6. Vue——方法(methods)

    我们用 methods 选项向组件实例添加方法,它应该是一个包含所需方法的对象: <div id="app"></div> <script> c ...

  7. Git三大区域

    1.工作区 2.暂存区 3.版本库

  8. 前端项目npm install安装报错:code ERESOLVE ERESOLVE could not resolve

    背景:使用npm 安装依赖的时候,发现报了如下的错误: npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tr ...

  9. Windows库链接报错

    问题回溯 今天拿到别人已经编译好的库,发现在链接的时候出现了报错 [9/9 12.7/sec] Linking CXX shared module bin\plugins\AsensingPlugin ...

  10. 解决TrueNAS中Smb共享文件路径不区分大小写的问题

    问题 在Truenas中, 默认的smb文件分享中, 文件夹是不区分大小写的. 这在一些情况下会导致无法重命名等问题, 严重时可能会造成拷贝文件时的全文件夹文件丢失. 这是linux下的情况, 在已存 ...