欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 艺术 > 26届JAVA 学习日记——Day12

26届JAVA 学习日记——Day12

2025/4/19 9:46:22 来源:https://blog.csdn.net/MapleLea1f/article/details/143896677  浏览:    关键词:26届JAVA 学习日记——Day12


2024.11.19 周二
许久不见,甚是想念。时隔周六、周日、周一,又准备开始打卡,许多课的结课大作业把我的计划打乱许多,因此许久没有打卡。

今日学习内容也不算多,课业和项目都比较花时间,时间花在项目上八股的学习时间就偏少。

八股

类初始化和类加载

创建对象的过程

在这里插入图片描述

  1. 类加载检查:虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池(回顾:常量池存储类和接口中的常量,包括字面值常量、符号引用、以及运行时常量池,同时常量池属于方法区的存储内容,而元空间是方法区的具体实现)中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化过,如果没有,那必须先执行相应的类加载过程
  2. 分配内存:在类加载检查通过后,接下来虚拟机将为新生对象分配内存。对象所需的内存大小类加载完成后便可确定,为对象分配空间的任务等同于把一块确定大小的内存从Java堆(回顾:根据 JVM8 规范,JVM 运行时内存共分为虚拟机栈、堆、元空间、程序计数器、本地方法栈五个部分。堆内存是 JVM 所有线程共享的部分,在虚拟机启动的时候就已经创建)中划分出来。
  3. 初始化零值:内存分配完成后,虚拟机需要将分配到的内存空间都初始化为零值(不包括对象头),这一步操作保证了对象的实例字段在Java代码中可以不赋初始值就直接使用,因为程序能访问到这些字段的数据类型所对应的零值。
  4. 进行必要设置,比如对象头:初始化零值完成后,虚拟机要对对象进行必要的设置,例如这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的GC分代年龄等信息。这些信息存放在对象头中。另外,根据虚拟机当前运行状态的不同,如是否启用偏向锁等,对象头会有不同的设置方式。

什么是偏向锁?
如果一个锁大多数时间都被同一个线程访问,那么就可以假设这个锁在将来也极有可能被同一个线程访问,从而省去一些不必要的检查,提高程序的性能。但是,如果有其他线程开始竞争这个锁,那么偏向锁就会撤销,回复到更严格的锁状态。

  1. 执行init方法:在上面工作完成后,从虚拟机的视角来看,一个新的对象已经产生,但从Java程序的视角来看,对象创建才刚开始,因为构造函数,即class文件中的方法还没有执行,所有的字段仍然为零,对象需要的其他资源和状态信息还没有按照预定的意图构造完成。所以一般来说,执行new指令之后还会接着执行方法,将对象按照程序员的意愿进行初始化,如此一个真正可用的对象才算被完成构造出来。
对象的生命周期

对象的生命周期包括 创建、使用、销毁 三个阶段:

  • 创建:对象通过关键词new在堆内存中被实例化,构造函数被调用,对象的内存空间被分配。
  • 使用:对象被引用并执行相应的操作,可以通过引用访问对象的属性和方法,在程序运行过程中被不断使用。
  • 销毁:当对象不再被引用时,通过垃圾回收机制自动回收对象所占用的内存空间。垃圾回收器会在适当的时候检测并回收不再被引用的对象,释放对象占用的内存空间,完成对象的销毁过程。
类加载过程 和 双亲委派原则

类从被加载到虚拟机内存开始,到卸载出内存为止,它的整个生命周期包括以下 7 个阶段:

在这里插入图片描述
其中Java 的类加载过程分为三个主要步骤:加载、链接、初始化

  • 第一阶段——加载(Loading)

通过类的全限定名(包名 + 类名),获取到该类的.class文件的二进制字节流,将二进制字节流所代表的静态存储结构,转化成方法区运行时的数据结构,在内存中生成一个代表该类的Java.lang.Class对象,作为方法区这个类的各种数据的访问入口。

Java将字节码数据从不同的数据源读取到JVM中,并映射为JVM认可的数据结构(Class对象)。

数据源可能是各种各样的形态,如jar文件、class文件,甚至是网络数据源等;如果输入数据不是 ClassFile 的结构,就会抛出ClassFormatError

  • 第二阶段——链接(Linking)

类加载过程的核心步骤,简单来说指 将原始的类定义信息平滑地转化入JVM运行的过程中。此处可进一步细分成三个步骤。

验证(verification),是虚拟机安全的重要保障,JVM需要核验字节信息是否符合Java虚拟机规范,否则被认为是VerifyError,如此一来就防止恶意信息或者不合规的信息危害JVM的运行,验证阶段有可能触发更多class的加载。

准备(preparation),创建类或接口中的静态变量(static),并初始化静态变量的初始值。但此处的"初始化"和"显式初始化阶段"存在区别,此处侧重点在于分配所需要的内存空间,不会去执行更进一步的JVM指令。

解析(resolution),将常量池的符号引用(symbolic reference)替换为直接引用。

  • 第三阶段——初始化(initialization)

真正地去执行类初始化地代码逻辑,包括静态字段赋值的动作,以及执行类定义中的静态初始化块内的逻辑,编译器在编译阶段就会把这部分逻辑整理完成,父类型的初始化逻辑优先于当前类型的逻辑。

public class Example {// 静态字段public static int staticField = 10;// 静态常量public static final String STATIC_CONSTANT = "This is a static constant";// 静态初始化块static {// 在这里可以进行静态字段的赋值或其他初始化操作System.out.println("Inside static initializer block.");staticField = 20; // 改变静态字段的值}// 构造函数public Example() {System.out.println("Inside constructor.");}// 主方法,程序的入口点public static void main(String[] args) {// 输出静态字段的值System.out.println("Static field value: " + staticField);// 输出静态常量的值System.out.println("Static constant value: " + STATIC_CONSTANT);// 创建类的实例,观察构造函数的调用new Example();}
}

双亲委派模型:当类加载器(Class-Loader)试图加载某个类型的时候,除非父加载器找不到相应类型,否则尽量将这个任务代理给当前加载器的父加载器去做。使用委派模型的目的是避免重复加载Java类型。

算法

560.和为k的子数组(枚举)

项目

苍穹外卖

尽管沉寂了许久,但是项目还是花了点时间抽空在做。

​​在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词