一、目录

二、类加载机制流程

1、什么是类加载机制?

  JVM把class文件加载到内存里面,并对数据进行校验、准备、解析和初始化,最终能够被形成被JVM可以直接使用的Java类型的过程。

2、类加载流程图

3、加载

  1. 将class文件加载在内存中。
  2. 将静态数据结构(数据存在于class文件的结构)转化成方法区中运行时的数据结构(数据存在于JVM时的数据结构)。
  3. 在堆中生成一个代表这个类的java.lang.Class对象,作为数据访问的入口。

4、链接

 链接就是将Java类的二进制代码合并到java的运行状态中的过程。

  • 验证:确保加载的类符合JVM规范与安全。
  • 准备:为static变量在方法区中分配空间,设置变量的初始值。例如static int a=3,在此阶段会a被初始化为0,其他数据类型参考成员变量声明。
  • 解析:虚拟机将常量池的符号引用转变成直接引用。例如"aaa"为常量池的一个值,直接把"aaa"替换成存在于内存中的地址。
    • 符号引用:符号引用以一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时能无歧义地定位到目标即可。符号引用与虚拟机实现的内存布局无关,引用 的目标并不一定已经加载到内存中。
    • 直接引用:直接引用可以是直接指向目标的指针、相对偏移量或是一个能间接定位到目标的句柄。直接引用是与虚拟机实现的内存布局相关的,如果有了直接引用,那么引用的目标必定已经在内存中存在。

5、初始化

  初始化阶段是执行类构造器<clinit>()方法。在类构造器方法中,它将由编译器自动收集类中的所有类变量的赋值动作(准备阶段的a正是被赋值a)和静态变量与静态语句块static{}合并,初始化时机后续再聊。

6、使用

  正常使用。

7、卸载

  GC把无用对象从内存中卸载。

三、类加载与初始化时机

1、类加载时机

  当应用程序启动的时候,所有的类会被一次性加载吗?估计你早已知道答案,当然不能,因为如果一次性加载,内存资源有限,可能会影响应用程序的正常运行。那类什么时候被加载呢?例如,A a=new A(),一个类真正被加载的时机是在创建对象的时候,才会去执行以上过程,加载类。当我们测试的时候,最先加载拥有main方法的主线程所在类。

2、类初始化时机

 主动引用(发生类初始化过程)

  1. new一个对象。
  2. 调用类的静态成员(除了final常量)和静态方法。
  3. 通过反射对类进行调用。
  4. 虚拟机启动,main方法所在类被提前初始化。
  5. 初始化一个类,如果其父类没有初始化,则先初始化父类。

 被动引用(不会发生类的初始化)

  1. 当访问一个静态变量时,只有真正声明这个变量的类才会初始化。(子类调用父类的静态变量,只有父类初始化,子类不初始化)。
  2. 通过数组定义类引用,不会触发此类的初始化。
  3. final变量不会触发此类的初始化,因为在编译阶段就存储在常量池中。

四、图解分析类加载

 public class ClassLoaderProduce {
static int d=3;
static{
System.out.println("我是ClassLoaderProduce类");
}
public static void main(String [] args){
int b=0;
String c="hello";
SimpleClass simpleClass=new SimpleClass();
simpleClass.run();
}
} class SimpleClass{
static int a=3;
static{
a=100;
System.out.println(a);
} public SimpleClass(){
System.out.println("对类进行加载!");
} public void run(){
System.out.println("我要跑跑跑!");
}
}

步骤一:装载ClassLoaderProduce类,在方法区生成动态数据结构(静态变量、静态方法、常量池、类代码),并且在堆中生成java.lang.Class对象;然后进行链接

步骤二:初始化:把static{}与静态变量合并存放在类构造器当中,对静态变量赋值。 1-5行执行完毕。

步骤三:执行main方法,首先在栈里面生成一个main方法的栈祯,定义变量b、c,注意此处的变量b、c存储的常量池存储的变量的地址,如图所示。

步骤四:创建SimpleClass对象;跟上面步骤类似:加载-链接-初始化。然后,调用run()方法的时候,它会通过classLoader局部变量的地址寻找到类的class对象并且调用run()方法

最新文章

  1. 【NLP】揭秘马尔可夫模型神秘面纱系列文章(一)
  2. 使用FastReport打印二维码
  3. c = (a / b, a%b) 运算输出顺序
  4. Silverlight开源框架SL提供便捷的二次开发银光框架
  5. Linux命令(14)文件和文件夹权限管理:chmod
  6. HTML5 内联框架iFrame
  7. 在32位Windows 8或Windows 7上安装Windows Phone 8 SDK
  8. Xshell4连接Linux后 win快捷键锁屏
  9. pyqt sender()学习
  10. Eclipse 乱码解决方案(UTF8 -- GBK)
  11. Mysql 外键设置
  12. 墙体裂缝推荐的情况下驱动的PhoneGap入门,早看早收据
  13. 【原创】构建高性能ASP.NET站点 第七章 如何解决内存的问题(前中篇)—托管资源优化—监测CLR性能
  14. Github 开源:高效好用的对象间属性拷贝工具:升讯威 Mapper( Sheng.Mapper)
  15. Python爬虫从入门到放弃(二十)之 Scrapy分布式原理
  16. 【C#】数据库脚本生成工具(二)
  17. ATS 分级缓存
  18. 你不知道的JS之作用域和闭包(二)词法作用域
  19. SQLServer之创建LOGON触发器
  20. 微信小程序换皮肤,动态切换菜单栏和导航栏的样式,动态修改TabBar和NavigationBar

热门文章

  1. 如何实现session跨服务器共享
  2. Xshell多版本被曝存在后门,了解紧急响应修复预案
  3. [Other] 应用下载网站的APK/IPA等常见MIME设置
  4. 安装Nginx并为node.js设置反向代理
  5. POJ 1129
  6. Maven 上传本地包到仓库 (来源于同事(gagahjt)的笔记本)
  7. ★ phpStudy安装SSL证书实现https链接
  8. Mac 下安装node.js(转载)
  9. sql 函数字符串处理
  10. windows下安装并使用redis