JVM相关知识

1Java类的生命周期:Java编译器编译生成class文件,从加载到卸载的全过程。

当我们使用命令来执行某一个Java程序(比如Test.class)的时候:java Test

java.exe 会帮助我们找到JRE ,接着找到位于JRE内部的 jvm.dll ,这才是真正的Java虚拟机器 , 最后加载动态库,激活Java虚拟机器。 虚拟机器激活以后,会先做一些初始化的动作,比如说读取系统参数等。一旦初始化动作完成之后,就会产生第一个类装载器 ―― Bootstrap Loader(启动类装载器 ) 。Bootstrap Loader所做的初始工作中,除了一些基本的初始化动作之外,最重要的就是加载 Launcher.java 之中的 ExtClassLoader(扩展类装载器) ,并设定其 Parent为null,代表其父加载器为 BootstrapLoader 。然后Bootstrap Loader再要求加载Launcher.java之中的 AppClassLoader(用户自定义类装载器 ) ,并设定其 Parent为之前产生的 ExtClassLoader 实体。这两个加载器都是以静态类的形式存在的。
这里要请大家注意的是,Launcher$ExtClassLoader.class 与 Launcher$AppClassLoader.class 都是由Bootstrap Loader所加载,所以Parent和由哪个类加载器加载没有关系。 

JVM相关知识JVM相关知识

A、加载:Jvm把字节码输入到内存。(jvm级别加载器在启动的时候就会默认把Java_home/lib里面的系统常用的类加载到Jvm中。其他第三方类,要用去找,找到就缓存,要用就到缓存中去找。)

jvm加载干的事:

  • 类的全限定名——获取——二进制字节流;
  • 字节流中的静态存储结构——转换——方法区运行时数据结构;
  • 在Java堆中——生成——代表该类Java.lang.class对象——作为方法区的数据访问入口。

B、连接:Jvm将内存中的类的二进制数据合并到jvm的运行时环境(jre)中。

jvm连接干的事:

  • 验证:class文件是否合法(符号,文件格式等是否合乎规范)。(目的:避免有人恶意编写class文件)
  • 准备:为静态变量分配内存,并设置jvm默认初始值。(八种基本类型都默认为0,引用类型默认为null,带有final static的常量默认为自己本身设置的值)
  • 解析:常量池中的符号引用转换为直接引用。(Jvm在解析时将show方法名转换为07164这种直接地址)

C、初始化:Jvm根据一个类是否被直接引用了来进行初始化。

直接引用的五种情况:如果没有初始化就直接进行初始化。

  • 遇到new,getstatic,putstatic,invokestatic这些字节码指令时。(new实例化类,读取或者设置类静态字段,执行静态方法)、
  • 使用Java.lang.reflect.*方法对类进行反射调用时。
  • 初始化一个类时,父类没有初始化,就先初始化父类。
  • Jvm启动时,需要指定一个执行的主类(包含static void main(String[] args)) 
  • 用class.forName(String classname);来加载类的时候也会初始化。

 2.Jvm的“编译时优化”,当编译器:String a='a'+'b'+1时,会自动编译成:String a='ab1';编译时能优化的内容只能来自常量池中,不能来自对象。