JVM核心之JVM运行和类加载全过程
为什么研究类加载全过程?
- 有助于连接JVM运行过程
- 更深入了解java动态性(解热部署,动态加载),提高程序的灵活性
类加载机制
- JVM把class文件加载到内存,并对数据进行校验、解析和初始化,最终形成JVM可以直接使用的java类型的全过程。
- 加载
- 将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区中的运行时数据结构,在堆中生成一个代表这个类的java.lang.Class对象,作为方法区类数据的访问入口,这个过程需要类加载器参与。
- 链接 将java类的二进制代码合并到JVM的运行状态之中的过程
- 验证:确保加载的类信息符合JVM规范,没有安全方面的问题
- 准备:正式为类变量(static变量)分配内存并设置类变量初始值的阶段,这些内存都将在方法去中进行分配
- 解析:虚拟机常量池的符号引用替换为字节引用过程
- 初始化
- 初始化阶段是执行类构造器<clinit>()方法的过程。类构造器<clinit>()方法是由编译器自动收藏类中的所有类变量的赋值动作和静态语句块(static块)中的语句合并产生
- 当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化
- 虚拟机会保证一个类的<clinit>()方法在多线程环境中被正确加锁和同步
- 当范围一个Java类的静态域时,只有真正声名这个域的类才会被初始化
例1:
public class Demo01 {public static void main(String[] args) {A a = new A();System.out.println(a.width);} }class A{public static int width=100; //静态变量,静态域 fieldstatic{System.out.println("静态初始化类A");width = 300 ;}public A() {System.out.println("创建A类的对象");} }
分析:
说明:
内存中存在栈、堆(放创建好的对象)、方法区(实际也是一种特殊堆)
1、JVM加载Demo01时候,首先在方法区中形成Demo01类对应静态数据(类变量、类方法、代码…),同时在堆里面也会形成java.lang.Class对象(反射对象),代表Demo01类,通过对象可以访问到类二进制结构。然后加载变量A类信息,同时也会在堆里面形成a对象,代表A类。
2、main方法执行时会在栈里面形成main方法栈帧,一个方法对应一个栈帧。如果main方法调用了别的方法,会在栈里面挨个往里压,main方法里面有个局部变量A类型的a,一开始a值为null,通过new调用类A的构造器,栈里面生成A()方法同时堆里面生成A对象,然后把A对象地址付给栈中的a,此时a拥有A对象地址。
3、当调用A.width时,调用方法区数据。
当类被引用的加载,类只会加载一次
- 类的主动引用(一定会发生类的初始化)
- new一个类的对象
- 调用类的静态成员(除了final常量)和静态方法
- 使用java.lang.reflect包的方法对类进行反射调用
- 当虚拟机启动,java Demo01,则一定会初始化Demo01类,说白了就是先启动main方法所在的类
- 当初始化一个类,如果其父类没有被初始化,则先初始化它父类
- 类的被动引用(不会发生类的初始化)
- 当访问一个静态域时,只有真正声名这个域的类才会被初始化
- 通过子类引用父类的静态变量,不会导致子类初始化
- 通过数组定义类的引用,不会触发此类初始化
- 引用常量不会触发此类的初始化(常量在编译阶段就存入调用类的常量池中了)
- 当访问一个静态域时,只有真正声名这个域的类才会被初始化
例2:
public class Demo01 {static{System.out.println("静态初始化Demo01");}public static void main(String[] args) throws Exception {System.out.println("Demo01的main方法!");System.out.println(System.getProperty("java.class.path"));//主动引用 // new A(); // System.out.println(A.width); // Class.forName("com.sinosoft.test.A");//被动引用 // System.out.println(A.MAX); // A[] as = new A[10];System.out.println(B.width);//B类不会被加载} }class B extends A {static {System.out.println("静态初始化B");} }class A extends A_Father {public static int width=100; //静态变量,静态域 fieldpublic static final int MAX=100; static {System.out.println("静态初始化类A");width=300;}public A(){System.out.println("创建A类的对象");} }class A_Father extends Object {static {System.out.println("静态初始化A_Father");} }
JVM核心之JVM运行和类加载全过程相关推荐
- 第六篇 JVM核心机制之JVM运行和类加载全过程(一)
JVM核心之JVM运行和类加载全过程 为什么研究类加载全过程? 有助于连接JVM运行过程 更深入了解java动态性(解热部署,动态加载),提高程序的灵活性 类加载机制 JVM把class文件加载到内存 ...
- JVM核心——JVM运行和类加载全过程
1.类加载全过程 (1)类加载机制 JVM把class文件加载到内存,并对数据进行校验.解析和初始化,最终形成JVM可以直接使用的Java类型的过程. 加载 将class文件字节码内容加载到内存中,并 ...
- 【随笔】JVM核心:JVM运行和类加载
前言 本篇博客将写一点关于JVM的东西,涉及JVM运行时数据区.类加载的过程.类加载器.ClassLoader.双亲委派机制.自定义类加载器等,这些都是博主自己的一点理解,如果有误,欢迎大家评论拍砖~ ...
- JVM运行和类加载全过程
一. 为什么研究类加载全过程 有助于了解JVM运行过程 更深入了解java动态性(了解热部署.动态加载)提高程序的灵活性. 二. 类加载机制 JVM把class文件加载到内存,并对数据进行校验.解析和 ...
- 第七篇 JVM核心机制之JVM运行和类加载全过程(二)
分析: 说明: 内存中存在栈.堆(放创建好的对象).方法区(实际也是一种特殊堆) 1.JVM加载Demo01时候,首先在方法区中形成Demo01类对应静态数据(类变量.类方法.代码-),同时在堆里面 ...
- 第十篇 JVM核心机制之JVM运行和类加载全过程(五)
加密.解密操作 加密操作 1 /** 2 * 3 * 加密操作 4 * 5 * @author Zhang XiaoDao 6 * 7 */ 8 public class EncrpUtil { 9 ...
- jvm运行时类加载机制_JVM体系结构:JVM类加载器和运行时数据区
jvm运行时类加载机制 各位读者好! 在JVM系列的上一篇文章中,开发人员了解了Java虚拟机(JVM)及其体系结构. 本教程将帮助开发人员正确回答以下主题的问题: ClassLoader子系统 运行 ...
- jdk包含java语言核心的类_1.1 jvm核心类加载器--jdk源码剖析
目录 前提: 运行环境 1. 类加载的过程 1.1 类加载器初始化的过程 1.2 类加载的过程 1.3 类的懒加载 2. jvm核心类加载器 3. 双亲委派机制 4. 自定义类加载器 5. tomca ...
- 深入JVM系列(三)之类加载、类加载器、双亲委派机制与常见问题
转载自 深入JVM系列(三)之类加载.类加载器.双亲委派机制与常见问题 一.概述 定义:虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用 ...
最新文章
- POJ 2299 Ultra-QuickSort(树状数组+离散化)
- Eclipse调试Android开发工具ADB
- 项目中常用的 iOS 第三方库
- 2018年第九届省赛C/C++A组第3题——乘积尾零
- JFinal问题整理
- SD-WAN新价值:中企通信与Fortinet强强联合 安全先行
- 苹果html5跑分排行,UC浏览器HTML5跑分创新高 升全球第一
- 编程体系结构(01):Java编程基础
- [已修正]安装struts找不到tld文件
- C语言中的system函数参数详解
- 2018年度总结(阉割版)
- 零信任体系下的企业数据安全建设路径
- 智慧文娱,阿里巴巴文娱技术探索之路
- TensorFlow 2 和 Keras 高级深度学习:11~13
- 【高效开发工具系列】API工具
- 「底层原理」一层层剥开文件系统的面纱,彻底理解Linux文件系统
- 网络号 IP地址 子网掩码如何计算
- 如何将你的网站提交到Google
- 如何发表一篇核心期刊论文
- Python 处理POS标签