宅家36天咸鱼翻身入职腾讯,Zookeeper一致性级别分析,

隔壁的老郭 2021-09-15 08:15:09
java 后端 程序员


类的生命周期

类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载,验证,准备,解析,初始化,使用,卸载这7个阶段.其中其中验证、准备、解析3个部分统称为连接.

宅家36天咸鱼翻身入职腾讯,Zookeeper一致性级别分析,_程序员

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

注意,这里的几个阶段是按顺序开始,而不是按顺序进行或完成,因为这些阶段通常都是互相交叉地混合进行的,通常在一个阶段执行的过程中调用或激活另一个阶段。

加载:查找并加载类的二进制数据

在加载阶段,虚拟机需要完成以下3件事情:

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

宅家36天咸鱼翻身入职腾讯,Zookeeper一致性级别分析,_后端_02

验证:确保被加载的类的正确性

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

  • 文件格式验证: 验证字节流是否符合Class文件格式的规范;例如: 是否以0xCAFEBABE开头、主次版本号是否在当前虚拟机的处理范围之内、常量池中的常量是否有不被支持的类型。
  • 元数据验证:对字节码描述的信息进行语义分析(注意: 对比javac编译阶段的语义分析),以保证其描述的信息符合Java语言规范的要求;例如: 这个类是否有父类,除了java.lang.Object之外。
  • 字节码验证:通过数据流和控制流分析,确定程序语义是合法的、符合逻辑的。
  • 符号引用验证:确保解析动作能正确执行。

验证阶段是非常重要的,但不是必须的,它对程序运行期没有影响,如果所引用的类经过反复验证,那么可以考虑采用-Xverifynone参数来关闭大部分的类验证措施,以缩短虚拟机类加载的时间。

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

准备阶段是正式为类变量分配内存并设置类变量初始值的阶段,这些变量所使用的内存都将在方法区中进行分配

该阶段的注意事项:

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

比如:假设一个类变量的定义为: public static int value = 3;那么变量value在准备阶段过后的初始值为0,而不是3,因为这时候尚未开始执行任何Java方法,而把value赋值为3的put static指令是在程序编译后,存放于类构造器()方法之中的,所以把value赋值为3的动作将在初始化阶段才会执行。

  • 对基本数据类型来说,对于类变量(static)和全局变量,如果不显式地对其赋值而直接使用,则系统会为其赋予默认的零值,而对于局部变量来说,在使用前必须显式地为其赋值,否则编译时不通过。

  • 对于同时被staticfinal修饰的常量,必须在声明的时候就为其显式地赋值,否则编译时不通过;而只被final修饰的常量则既可以在声明时显式地为其赋值,也可以在类初始化时显式地为其赋值,总之,在使用前必须为其显式地赋值,系统不会为其赋予默认零值。

  • 对于引用数据类型reference来说,如数组引用、对象引用等,如果没有对其进行显式地赋值而直接使用,系统都会为其赋予默认的零值,即null

  • 如果在数组初始化时没有对数组中的各元素赋值,那么其中的元素将根据对应的数据类型而被赋予默认的零值。

  • 如果类字段的字段属性表中存在ConstantValue属性,即同时被final和static修饰,那么在准备阶段变量value就会被初始化为ConstValue属性所指定的值。假设上面的类变量value被定义为: public static final int value = 3;编译时Javac将会为value生成ConstantValue属性,在准备阶段虚拟机就会根据ConstantValue的设置将value赋值为3。我们可以理解为static final常量在编译期就将其结果放入了调用它的类的常量池中

解析:把类中的符号引用转换为直接引用

解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程,解析动作主要针对接口字段类方法接口方法方法类型方法句柄调用点限定符7类符号引用进行。符号引用就是一组符号来描述目标,可以是任何字面量。

直接引用就是直接指向目标的指针、相对偏移量或一个间接定位到目标的句柄。

初始化:对类的静态变量,静态代码块执行初始化操作

初始化,为类的静态变量赋予正确的初始值,JVM负责对类进行初始化,主要对类变量进行初始化。在Java中对类变量进行初始值设定有两种方式:

  • 声明类变量是指定初始值
  • 使用静态代码块为类变量指定初始值

类初始化的步骤

  • 假如这个类还没有被加载和连接,则程序先加载并连接该类
  • 假如该类的直接父类还没有被初始化,则先初始化其直接父类
  • 假如类中有初始化语句,则系统依次执行这些初始化语句

触发类初始化的时机

只有当对类的主动使用的时候才会导致类的初始化,类的主动使用包括以下六种:

  • 使用new关键字实例化对象的时候。

  • 读取或设置一个类型的静态字段(被final修饰、已在编译期把结果放入常量池的静态字段除外)的时候。

  • 调用一个类型的静态方法的时候。

  • 使用java.lang.reflect包的方法对类型进行反射调用的时候,如果类型没有进行过初始化,则需要先触发其初始化。

  • 当初始化类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化。

  • 当虚拟机启动时,用户需要指定一个要执行的主类(包含main()方法的那个类),虚拟机会先初始化这个主类。

以下几种情况不会执行类初始化

  1. 通过子类引用父类的静态字段,只会触发父类的初始化,而不会触发子类的初始化。

  2. 定义对象数组,不会触发该类的初始化。

  3. 常量在编译期间会存入调用类的常量池中,本质上并没有直接引用定义常量的类,不会触 发定义常量所在的类。

  4. 通过类名获取 Class 对象,不会触发类的初始化。

  5. 通过 Class.forName 加载指定类时,如果指定参数 initialize 为 false 时,也不会触发类初 始化,其实这个参数是告诉虚拟机,是否要对类进行初始化。

  6. 通过 ClassLoader 默认的 loadClass 方法,也不会触发初始化动作。

使用

类访问方法区内的数据结构的接口, 对象是Heap区的数据。

卸载

Java虚拟机将结束生命周期的几种情况

  • 执行了System.exit()方法
  • 程序正常执行结束
  • 程序在执行过程中遇到了异常或错误而异常终止
  • 由于操作系统出现错误而导致Java虚拟机进程终止

类加载器

什么是类加载器

虚拟机设计团队把类加载阶段中的“通过一个类的全限定名来获取描述此类的二进制字节流”这个动作放到Java虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的类。 实现这个动作的代码模块称为“类加载器”。

类加载器的层次

宅家36天咸鱼翻身入职腾讯,Zookeeper一致性级别分析,_后端_03

双亲委派模型要求除了顶层的启动类加载器外,其余的类加载器都应有自己的父类加载器。不过这里类加载器之间的父子关系一般不是以继承(Inheritance)的关系来实现的,而是通常使用组合(Composition)关系来复用父加载器的代码。

从Java虚拟机的角度来讲,只存在两种不同的类加载器:一种是启动类加载器(Bootstrap ClassLoader),这个类加载器使用C++语言实现,是虚拟机自身的一部分;另一种就是所有其他的类加载器,这些类加载器都由Java语言实现,独立于虚拟机外部,并且全都继承自抽象类java.lang.ClassLoader。

从Java开发人员的角度来看,类加载器还可以划分得更细致一些,绝大部分Java程序都会使用到以下3种系统提供的类加载器:

启动类加载器(Bootstrap ClassLoader)

这个类将器负责将存放在<JAVA_HOME>\lib目录中的,或者被-Xbootclasspath参数所指定的路径中的,并且是虚拟机识别的(按照文件名识别,如rt.jar、tools.jar,名字不符合的类库即使放在lib目录中也不会被加载)类库加载到虚拟机内存中。

扩展类加载器(Extension ClassLoader)

这个加载器由sun.misc.Launcher$ExtClassLoader实现,它负责加载<JAVA_HOME>\lib\ext目录中的,或者被java.ext.dirs系统变量所指定的路径中的所有类库,开发者可以直接使用扩展类加载器。

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

这个类加载器由sun.misc.Launcher$AppClassLoader来实现。由于应用程序类加载器是ClassLoader类中的getSystem-ClassLoader()方法的返回值,所以有些场合中也称它为“系统类加载器”。

它负责加载用户类路径(ClassPath)上所有的类库,开发者同样可以直接在代码中使用这个类加载器。如果应用程序中没有自定义过自己的类加载器,一般情况下这个就是程序中默认的类加载器。

我们的应用程序都是由这3种类加载器互相配合进行加载的,如果有必要,还可以加入自己定义的类加载器。

最后

由于篇幅限制,小编在此截出几张知识讲解的图解

 CodeChina开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频】

宅家36天咸鱼翻身入职腾讯,Zookeeper一致性级别分析,_后端_04

宅家36天咸鱼翻身入职腾讯,Zookeeper一致性级别分析,_Java_05

宅家36天咸鱼翻身入职腾讯,Zookeeper一致性级别分析,_Java_06

宅家36天咸鱼翻身入职腾讯,Zookeeper一致性级别分析,_Java_07

宅家36天咸鱼翻身入职腾讯,Zookeeper一致性级别分析,_后端_08

版权声明
本文为[隔壁的老郭]所创,转载请带上原文链接,感谢
https://blog.51cto.com/u_15302416/3888218

  1. Java + SSM Social Insurance Pension System for Computer Graduation Design
  2. Java inheritance
  3. Java method review
  4. java JVM
  5. Java Basics
  6. Java file operation object IO stream
  7. Java console reads multi character input and output
  8. Java simple array sorting
  9. In addition to MySQL master-slave, you have another choice, Galera
  10. Configuration standard dockerfile et docker-composer.yml
  11. 字节大神强推千页PDF学习笔记,2021Java开发学习路线,
  12. 字节大牛耗时八个月又一力作,靠这份Java知识点PDF成功跳槽,
  13. 字节大牛教你手撕Java学习,最新大厂程序员进阶宝典,
  14. Comment l'automne est - il beau?Ces 24 ensembles de modèles d'automne et d'hiver sont grands, minces et vieillissants
  15. 字節大牛教你手撕Java學習,最新大廠程序員進階寶典,
  16. 字節大牛耗時八個月又一力作,靠這份Java知識點PDF成功跳槽,
  17. Byte Bull vous apprend à déchiqueter Java à la main, le dernier dictionnaire avancé des programmeurs de grandes usines,
  18. Byte Bull a pris huit mois à travailler dur et a réussi à changer d'emploi avec ce PDF Java Knowledge point.
  19. Byte God Push 1000 pages PDF Learning notes, 2021 Java Development Learning route,
  20. Five minutes to understand MySQL index push down
  21. Spring中@within与@target的一些区别
  22. 力荐:提高千倍效率的一些 Java 代码小技巧
  23. Redis技术专题系列之帮你从底层彻底吃透RDB技术原理(基础篇)
  24. Juan Benet et vitalik buterin discutent des réflexions sur les médias sociaux décentralisés
  25. Ipfs Weekly Report 152 | pinata launched "submarining"
  26. Performance optimization issue 03 - HTTP request optimization
  27. JavaScript genrator generator
  28. 字节跳动Java面试全套真题解析在互联网火了,面试大厂应该注意哪些问题?
  29. 字节跳动Java社招,2021年阿里 腾讯 快手offer都已拿到!
  30. 用Java实现红黑树
  31. 使用Redis Stream来做消息队列和在Asp.Net Core中的实现
  32. 海量列式非关系数据库HBase 架构,shell与API
  33. Redis Technology Topic Series vous aide à comprendre les principes de la technologie rdb du Bas (Basic)
  34. Conseils: quelques conseils pour améliorer l'efficacité du Code Java
  35. Quelques différences entre @ within et @ Target au printemps
  36. 海量列式非關系數據庫HBase 架構,shell與API
  37. Architecture, Shell et API de base de données non relationnelle à grande échelle
  38. Mise en œuvre de l'arbre Rouge et noir en Java
  39. Byte Hopping Java Service Call, 2021 Alibaba Tencent Express offer a été obtenu!
  40. Byte Jump Java interview Full Set of true Problems Analysis in Internet fire, interview Factory should pay attention to what Problems?
  41. La dernière réponse à l'entrevue de développement Android, l'hiver froid de l'industrie
  42. A young Lexus, the new NX refuses to be mediocre and mature
  43. Interprétation approfondie de l'équipe sin7y: application de plookup dans la conception de zkevm
  44. Java basic knowledge point Combing, redis Common Data Structures and Using scenario Analysis,
  45. Five minutes to understand MySQL index push down
  46. Data structure and algorithm (XI) -- algorithm recursion
  47. Programmation asynchrone Java scirp, développement frontal de base
  48. Java basic knowledge point video, three sides ant Gold Clothing successfully obtained offer,
  49. Oracle Linux bascule le noyau uek vers le noyau rhck pour résoudre les problèmes de compatibilité acfs
  50. After the grand finale of spring in jade mansion, after reading many comments, I began to sympathize with white deer
  51. 字节跳动Java高级工程师,统一命名服务、集群管理、分布式应用?
  52. 字节跳动Java高级工程师,深入分布式缓存从原理到实践技术分享,
  53. 字节跳动第三轮技术面,阿里P8架构师Java大厂面试题总结,
  54. 字节跳动社招Java面试,超通俗解析CountDownLatch用法和源码,
  55. 字节跳动最新开源,最经典的HashMap图文详解,
  56. 字節跳動第三輪技術面,阿裏P8架構師Java大廠面試題總結,
  57. Byte Jumping the Third Third Technical surface, Ali P8 Architect Java Factory Interview Question summary,
  58. L'ingénieur Java senior de Byte Hopping approfondit la mise en cache distribuée, du principe au partage de la technologie pratique.
  59. Byte Jump Java Senior Engineer, Unified Naming service, Cluster Management, Distributed application?
  60. Plusieurs méthodes de transfert de fichiers entre Windows et Linux