Java基础—JAVA类的生命周期问题

1.JDK与JRE的作用

当我们编写Java程序时,我们实际上是在使用一种高级编程语言,而计算机最终需要将这些高级语言转换成机器语言才能执行。在这个过程中,Java开发工具包(JDK)和Java运行时环境(JRE)扮演了重要角色:

  • JDK:JDK是一个完整的JAVA开发工具包,它包含了编译器(JAVA Compiler即javac)、库和开发工具。JDK的编译器作用就是把.java文件变成.class文件的过程,即把高级语言转化成编译语言(字节码)。
  • JRE:JRE是JAVA运行时环境,它包含了JAVA虚拟机(JVM)、JAVA核心类库和支持文件。其中重点就是JVM,JVM中包含了JVM解释器,它的作用是将Java程序编译后的字节码文件(.class文件)解释成机器语言,从而让计算机能够执行Java程序。

这一过程也就是为什么JAVA常被称为“半编译、半解释语言”(主编译)。
为什么说JAVA的生命周期要说到JDK和JRE,我是觉得了解Java程序从编写到运行再到结束的整个生命周期过程,不仅涉及到JDK和JRE的角色,还需要理解JAVA程序再不同阶段的处理和运行方式。
这种全面的了解可以帮助我们更好地理解Java地设计概念和底层结构,以及Java程序再运行时的行为和性能表现。

在上面的内容我们也可以得知,在字节码加载到内存前,其实还有一个编译过程就是 .java->.class,从这一步后,就是整个JAVA类生命周期的开始。

2. JAVA类的生命周期

  1. 加载(Loading):ClassLoader将字节码文件加载到内存中,并创建一个代表该类的Class文件。
  2. 链接(Linking)
    • 验证(Verification):确保加载的类符合JVM规范,不会导致安全问题
    • 准备(Preparation):为类的静态变量分配内存,并设置默认初始值。
    • 解析(Resolution):将类、方法字段等符号引用解析为直接引用
  3. 初始化(Initialization):执行类的初始化代码,包括静态变量赋值和静态初始化块的执行。
  4. 运行(Running):实例化类并调用其方法,执行程序逻辑
  5. 卸载(Unloading):当类不再需要时,ClassLoader可以卸载类,并释放相关资源。

在这里插入图片描述

3.生命周期(类加载)—加载(Loading)

ClassLoader负责加载字节码文件(.class文件)到内存中。ClassLoader有三种:Bootstrap ClassLoader(启动类加载器)、Extension ClassLoader(扩展类加载器)和Application ClassLoader(应用程序类加载器)。它们会按照一定的顺序来尝试加载类文件,最终加载的类文件会被转换成二进制形式并存储在内存中。

一旦类文件被加载到内存中,JVM会为这些类创建对应的‘class’对象。这个对象包含了类的结构信息,比如类的方法、字段、构造函数等。‘Class’对象会被创建并存储在方法区,这个对象在整个类的生命周期都存在,直到程序结束才会被销毁。

在JAVA虚拟机(JVM)中,‘Class’对象通常都是存在方法区(Method Area)中的。方法区是一块用于存储类信息、常量、静态变量等数据的内存区域,它是线程共享的内存区域,在JVM启动时被创建。方法区属于堆内存的一部分,但是它有一些特殊行为,例如不会进行垃圾回收。
类的元数据信息和类的对象实例的存储空间是不同的,类元数据信息在方法区,实例对象是在堆内存中。

4.生命周期(类加载)—链接(Linking)

连接分为三个阶段:验证->准备->解析

  • 验证:确保加载的类符合JVM规范,不会导致安全问题。这个不过多解释,正常开发应该不会坑在这里。
  • 准备:为类的静态变量分配内存并设置初始值
    1. 为类静态变量分配内存空间。这时候静态变量会被分配到方法区中的静态变量区域。
    2. 设置静态变量的默认初始值。根据静态变量的类型赋予默认值。 例如,int 类型的默认值为 0,boolean 类型的默认值为 false,引用类型的默认值为 null。
      注意:准备阶段并不会真正为静态变量赋予程序中的指定值,而只是为它们分配内存并设置默认初始值。
  • 解析:在这个阶段,虚拟机将常量池中的符号引用替代为直接引用。
  1. 将类、方法、字段的符号引用转换为直接引用:在编译阶段,Java编译器生成的class文件会包含许多符号引用,比如类名、方法名、字段名等。在解析阶段,虚拟机会将这些符号引用替代为直接引用,指向内存中的实际数据结构,比如指向方法区中的方法表、字段表等。

符号引用:以一组符号描述所引用的目标。在编译时,因为类还没加载到方法区,java类并不知道引用的对象的实际地址,因此只能使用符号引用替代。比如com.Test类类引用了com.MyMO类,编译时Test类并不知道MyMo类的实际内存地址,因此只能使用符号com.MyMo
直接引用:通过对符号引用进行解析,找到引用的实际地址。

  1. 在Java虚拟机中,解析过程可以延迟到进行时进行,这种延迟解析方式可以提高程序性能。
    例子:延迟解析的一个例子是动态链接。在动态链接的情况下,方法的符号引用会被解析为实际的内存地址,但是这个解析过程可以延迟到方法被调用时进行,而不是在类加载阶段就完成。这样可以避免在类加载时就解析所有的方法引用,提高了程序的性能。

5. 生命周期(类加载)—初始化(Initialization)

在Java中,类的初始化阶段是类加载过程的最后一个阶段,在这个阶段,JVM会执行类的初始化代码,包括静态变量赋值和静态初始化块的执行。

  1. 静态变量赋值:在准备阶段,静态变量被分配了内存并设置了默认值,而在初始化阶段,会执行静态变量的赋值操作,将静态变量设置为程序中指定的值。
  2. 静态初始化块的执行:类中的静态初始化块会在初始化阶段被执行。静态初始化块可以包含任意的java代码,用于完成一些静态资源的初始化工作。
  3. 可执行静态方法: 只有在静态方法被显式调用或者静态方法在静态初始化块中被调用时,才会执行这些静态方法

至此,类的加载完毕,一共经历四个阶段,规范检查(检查)->类元数据加载并赋值默认值(准备)->符号引用变为直接引用(解析)->静态变量赋值、静态代码块执行(初始化)

6.运行(Running)与卸载(Unloading)

  • 运行:在这个阶段,逻辑执行,类的实例被创建,并且可以通过调用实例方法执行程序功能
  • 卸载:类的卸载也是由ClassLoad进行管理的,通常在类加载器被垃圾回收时才会触发。正常不会触发
    在正常情况下,Java程序运行过程中很少会发生类的卸载。这是因为在Java虚拟机中,类的卸载通常需要满足下面条件:
    1. 类实例的引用数量为零:即没有任何类的实例被引用,包括静态变量对该类的引用。
    2. 类的ClassLoader被卸载:ClassLoader负责加载类到内存中,当ClassLoader被卸载时,它加载的类也会被卸载。
    3. 没有被其他类引用:即没有其他类通过反射等方式引用该类。
      在正常情况下,这些条件很难同时满足,所以类的卸载在正常程序运行时并不常见。但是,在某些特殊情况下,比如使用自定义的ClassLoader动态加载类时,可能会出现类的卸载。

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

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

相关文章

VR全景看房:超越传统的看房方式

近年来,新兴技术不断涌出,例如大数据、VR全景、人工智能、元宇宙等。随着科技不断发展,VR全景技术在房地产行业中的应用也是越发广泛,逐渐超越了传统的看房方式。今天,就让我们一起来深入探讨一下VR全景技术在VR看房中…

Weblogic 常规渗透测试环境

测试环境 本环境模拟了一个真实的weblogic环境,其后台存在一个弱口令,并且前台存在任意文件读取漏洞。分别通过这两种漏洞,模拟对weblogic场景的渗透。 Weblogic版本:10.3.6(11g) Java版本:1.6 弱口令 环境启动后…

一行代码极速部署:打造面向开发者的流计算平台

作者:Yingjun Wu TL;DR. curl https://risingwave.com/sh | sh在2021年初,我创立了RisingWave,目标是推广流计算技术的普及。在过去的三年中,我不断的向市场布道RisingWave,希望RisingWave能够在流计算这一市场中占…

【编程语言】C#语言相关知识

前言:我们在游戏开发的过程中,往往会通过游戏引擎结合编程语言的方式,来作为项目开发的手段。因此,了解相关语言的特性、发展和前沿知识,就显得相当必要。笔者这里结合自身的工作经验和学习心得,用简洁通俗…

springboot272车辆管理系统

基于SSM的车辆管理系统的设计与实现 摘要 当下,正处于信息化的时代,许多行业顺应时代的变化,结合使用计算机技术向数字化、信息化建设迈进。以前企业对于车辆信息的管理和控制,采用人工登记的方式保存相关数据,这种以…

HarmonyOS NEXT星河版——还是Android上套个壳吗?

这真的是我2024年听过最搞笑的话,就在前几天,居然还有人说鸿蒙OS就是安卓套个壳,简直无语! 你敢相信?就在前几天,我还听到有人说:鸿蒙os就是安卓上套一个壳。唉,我真是无语了。 哎&#xff0c…

docker容器启动rabbitmq

docker容器启动rabbitmq 一、RabbitMQ部署1.1.在线拉取mq镜像1.2.运行mq容器1.3.访问mq 二、RabbitMQ的集群2.1.集群分类2.1.设置 /etc/hosts文件 endl 一、RabbitMQ部署 1.1.在线拉取mq镜像 # 在线拉取 docker pull rabbitmq:3-management1.2.运行mq容器 docker run \ -e R…

SpringMVC基础之工作流程

文章目录 SpringMVC 的工作流程1. 总图2. DispatcherServlet3. 必需的配置4. 加载配置文件的两个时机5. 定义控制器6. 创建 JSP 视图 SpringMVC 的工作流程 1. 总图 如上图,Spring MVC 程序的完整执行流程如下: 用户通过浏览器发送请求,请求…

【NR 定位】3GPP NR Positioning 5G定位标准解读(十三)-DL-AoD定位

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

ts文件怎么无损转换mp4?这样设置转换模式~

TS格式(Transport Stream)的起源可追溯到数字电视广播领域。设计初衷是解决视频、音频等多媒体数据在传输和存储中的问题。采用一系列标准技术,TS格式让视频信号能够以流的形式传输,因此在数字电视、广播等领域得到广泛应用。 MP4…

Android 音频系统

导入 早期Linux版本采用的是OSS框架,它也是Unix及类Unix系统中广泛使用的一种音频体系。 ALSA是Linux社区为了取代OSS而提出的一种框架,是一个源代码完全开放的系统(遵循GNU GPL和GNU LGPL)。ALSA在Kernel 2.5版本中被正式引入后,OSS就逐步…

试卷上的水印如何去除?分享3种常用的方法!

在日常生活和工作中,我们经常会遇到一些带有水印的试卷或文档,这些水印不仅影响了我们的阅读体验,还可能对我们的工作和学习产生一定的困扰。那么,如何有效去除试卷上的水印呢?今天,就让我们一起来探讨这个…