Java技术专区-虚拟机系列-类加载机制(类的初始化)
类加载的生命周期:
加载 -> 验证 -> 准备 -> 解析 -> 初始化 -> 使用 -> 卸载
加载 -> 验证 -> 准备 -> 解析 -> 初始化 -> 卸载这6个阶段顺序是确定的,klass的加载过程一定会按照这个顺序执行。为了支持java的运行时绑定,解析阶段在某些情况下会在初始化之后才进行。
类的初始化阶段
对于
加载这个阶段是跟具体的虚拟机实现有关,对于整个类加载阶段最重要的就是初始化这个阶段.
JVM执行初始化的情况
对于Hotspot虚拟机而言,遇见以下这5种情况就需要进行
初始化:遇到
new、getstatic、putstatic、invokestatic,如果类还没进行初始化的时候就进行初始化。生成这4种指令最常见的就是:new一个实例化对象、读取或设置一个类的静态字段(被final修饰、已在编译时吧结果放在常量池的静态字段排除),已经调用一个类的静态方法时。
- java的反射对类进行反射调用。
- 初始化类之间,检测父类是否初始化,否则先初始化父类。
- 虚拟机启动时,用户需要制定一个要执行的主类(包含main方法的类),虚拟机会先初始化这个类
- 使用jdk7以上动态语言支持时,如果一个methodHandler实例最后的解析结果
REF_getstatic、REF_putstatic、REF_invokestatic的方法句柄,并且这个方法的句柄对应的类没有初始化的时候。
这里我们需要注意的点,上面的五种情况指的是主动的引用方式,除了上面5种主动引用之外的被动引用是不会触发初始化的.
类的被动引用实例:
情况一:通过子类来引用父类的静态字段,是只会执行父类的初始化而子类不会初始化的,但是Hotspot虚拟机下会触发子类的加载和验证。
情况二:声明一个数组类型的类。因为jvm会调用newarray生成一个继承自object的子类,这个类代表了对应的这个类型的数组类型。
情况三:A引用了B中
final修饰过的静态属性不会导致B的初始化,因为经过编译器的优化,A中引用的这个B的属性元素已经在编译时期存储到了A类下的常量池中,所以其实A下的引用来自于对自身常量池的引用。我们这里还需要注意的一点是接口和类不同的就是接口的父接口只有在真正被使用的时候才会被初始化
类的初始化之clinit方法
对于jvm而言,类的初始化也就是执行clinit方法,那么什么是clinit方法?
clinit方法是有编译器自动收集类中的所有变量的赋值动作和静态语句块中的语句合并产生的一个用于jvm执行类的初始化的方法。
需要注意以下几点:
clinit方法不需要显示的调用父类构造器,虚拟机会保证子类的clinit方法执行之前父类的clinit方法已经调用完毕,因此虚拟机中第一个被执行clinit方法的肯定是Object。clinit对于类和接口不是必须的,如果类中没有静态块,也没有对变量的赋值操作,编译器可以不为这个类生产clinit方法。执行接口的
clinit方法不需要先执行父接口的clinit方法,只有当父接口中定义的变量被使用,父接口才会初始化。另外接口的实现类在初始化也一样不会执行接口的clinit方法。jvm会保证一个类的
clinit方法在多线程环境下被正确加锁同步,也就是说类的初始化是线程安全的,同时需要注意的是,如果一个线程执行clinit方法时有很耗时的操作,就会阻塞其他也要初始化的这个类的线程。
验证猜想的小技巧
关于我们文章上述初始化过程中,如何验证,我们可以把代码在写在类的static块里,就能验证我买的猜想了。原理就在上文关于clinit方法中。
Java技术专区-虚拟机系列-类加载机制(类的初始化)的更多相关文章
- Java技术专区-虚拟机系列-虚拟机参数(常用)
基础参数系类(内存分配) -server:一定要作为第一个参数,在多个CPU时性能佳 -Xmn:young generation的heap大小,一般设置为Xmx的3.4分之一-Xms:初始Heap大小 ...
- Java技术专区-虚拟机系列-堆快照(获取)
1.JVM-堆快照(Snapshot) 1.1 输出方式-获取hprof文件 启动参数配置OOM时触发打印堆快照 (1)tomcat启动方式添加参数 (添加环境变量) export JAVA_OPTS ...
- java 复习整理(五 类加载机制与对象初始化)
类加载机制与对象初始化 一 . 类加载机制 类加载机制是指.class文件加载到jvm并形成Class对象的机制.之后应用可对Class对象进行实例化并调用.类加载机制可在运行时动态加载外部的类, ...
- Java虚拟机:类加载机制详解
版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! 大家知道,我们的Java程序被编译器编译成class文件,在class文件中描述的各种信息,最终都需要加载到虚拟机内存才能运行和使用,那么 ...
- java 虚拟机的类加载机制
Java 虚拟机的类加载机制 关于类加载机制: 虚拟机把描述类的数据从Class 文件加载到内存,并对数据进行效验.转换解析和初始化,最终 形成可以被虚拟机直接使用的Java 类型,就是虚拟机的类 ...
- java虚拟机的类加载机制
引言 我们写的代码是放在.java文件中,经过编译器编译后,转成.class文件.Class文件是一串二进制流,它可以被各平台的虚拟机所接受,实现跨平台. 虚拟机将描述类的数据从class文 ...
- 深入理解Java虚拟机(类加载机制)
文章首发于微信公众号:BaronTalk 上一篇文章我们介绍了「类文件结构」,这一篇我们来看看虚拟机是如何加载类的. 我们的源代码经过编译器编译成字节码之后,最终都需要加载到虚拟机之后才能运行.虚拟机 ...
- 【进阶之路】深入理解Java虚拟机的类加载机制(长文)
我们在参加面试的时候,经常被问到一些关于类加载机制的问题,也都会在面试之前准备的时候背好答案,但是我们是否有去深入了解什么是类加载机制呢?这段时间因为一些事情在家看了些书,这次就和大家分享一些关于Ja ...
- 深入理解Java虚拟机之类加载机制篇
概述 虚拟机把描述类的数据从 Class 文件加载到内存中,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,就是虚拟机的类加载机制. 在Java语言里面,类型的 ...
随机推荐
- 用swith语句来键入一个整数输出对应是星期几
基本格式:switch(表达式) { //基本数据类型可以接收byte,short,char,int 引用数据类型可以接收枚举(JDK1.5)String字符串(JDK1.7) case 值1: 语句 ...
- 递归算法介绍及Java应用实战
什么是递归算法 递归算法是把问题转化为规模缩小了的同类问题的子问题,然后递归调用函数(或过程)来表示问题的解.一个过程(或函数)直接或间接调用自己本身,这种过程(或函数)叫递归过程(或函数). 递归过 ...
- Oracle学习笔记<4>
多表查询 1.什么是多表查询? 一次select语句需要查询的内容来自于不止一张表. 同时从多张表中查询数据. 单表查询: select id,last_name,salary from s_emp ...
- 开发环境绑定host vue 返回 invalid host header
事情:使用域名绑定host为本机电脑ip,vue返回 invalid host header 原因:新版的webpack-dev-server出于安全考虑,默认检查hostname,如果hostnam ...
- springCloud的使用08-----服务链路追踪(sleuth+zipkin)
sleuth主要功能是在分布式系统中提供追踪解决方案,并且兼容支持了zipkin(提供了链路追踪的可视化功能) zipkin原理:在服务调用的请求和响应中加入ID,表明上下游请求的关系. 利用这些信息 ...
- docker--container的port映射
使用nginx为例 先运行nginx [root@localhost ~]# docker run --name web -d nginx Unable to find image 'nginx:la ...
- 44.Linked List Cycle II(环的入口节点)
Level: Medium 题目描述: Given a linked list, return the node where the cycle begins. If there is no cy ...
- C#读取Xml中出现”&”等特殊符号
原文:C#读取Xml中出现"&"等特殊符号 C#读取Xml中出现的特殊符号时用ASCII或者转定义名称代替.程序读进来后转成字符串后就自动变成相应的字符了,再度保存时会以正 ...
- Netflix:我们为什么要将GraphQL引入前端架构?
作者|Artem Shtatnov译者|无明 在这篇文章中,我们将分享 Netflix 在这些应用程序的前端架构中引入 GraphQL 所积累的经验. 在内部,我们把用于管理广告创建和组装的主要应用程 ...
- MariaDB 删除表
在本章中,我们将学习删除表. 表删除很容易,但记住所有删除的表是不可恢复的. 表删除的一般语法如下 - DROP TABLE table_name ; 存在执行表删除的两个选项:使用命令提示符或PHP ...