JVM原理理解

目录

  • JVM类加载机制
  • JVM本地方法栈
  • JVM堆分配
  • JVM引用类型
  • JVM类加载机制

JVM类加载机制

类加载顺序

类加载的过程包括:加载、连接、初始化,连接又分为:验证、准备、解析,所以说类加载一共分为5步:加载、验证、准备、解析、初始化。解析过程在某些情况下可能发生在初始化后。

类加载过程中的初始化时机
  • 在运行过程中遇到如下字节码指令时,如果类尚未初始化,那就要进行初始化:new、getstatic、putstatic、invokestatic

    1. 用new创建一个对象时(创建数组时只是创建了引用)。
    2. 设置、读取类的静态成员时(不包括final的静态对象)。
    3. 调用类的静态成员函数
  • 反射调用一个未初始化的类。

  • 优化初始化父类

  • 虚拟机优化初始化主类,main。

主动引用 与 被动引用

如直接满足以上四个条件称为主动引用,间接满眼称为被动引用

  • 主动引用例子:
public class A {
    public static String name = "name";
    static {
        System.out.println("初始化类A");
    }
}

public class B extends A {
    public static final String value = "value";
    static {
        System.out.println("初始化类B");
    }
}

public static void main(String[] args) {
    B b = new B();
}

//输出:
初始化类A
初始化类B
  • 被动引用例子:
public static void main(String[] args) {
    System.out.println(B.name);
}

//输出
初始化类A
name

name属于类A,A被直接引用,被动引用了类B

  • stativ final 的成员属于常量池,调用不会初始化类。
public static void main(String[] args) {
    System.out.println(B.value);
}

//输出
value
类初始化顺序
  • 普通类
    1. 静态属性:static 开头定义的属性
    2. 静态方法块: static {} 圈起来的方法块
    3. 普通属性: 未带static定义的属性
    4. 普通方法块: {} 圈起来的方法块
    5. 构造函数: 类名相同的方法
    6. 方法: 普通方法
public class LifeCycle {
    // 静态属性
    private static String staticField = getStaticField();
    // 静态方法块
    static {
        System.out.println(staticField);
        System.out.println("静态方法块初始化");
        System.out.println("Static Patch Initial");
    }
    // 普通属性
    private String field = getField();
    // 普通方法块
    {
        System.out.println(field);
        System.out.println("普通方法块初始化");
        System.out.println("Field Patch Initial");
    }
    // 构造函数
    public LifeCycle() {
        System.out.println("构造函数初始化");
        System.out.println("Structure Initial ");
    }

    public static String getStaticField() {
        String statiFiled = "Static Field Initial";
        System.out.println("静态属性初始化");
        return statiFiled;
    }

    public static String getField() {
        String filed = "Field Initial";
        System.out.println("普通属性初始化");
        return filed;
    }   
    // 主函数
    public static void main(String[] argc) {
        new LifeCycle();
    }
}

//输出
静态属性初始化
Static Field Initial
静态方法块初始化
Static Patch Initial
普通属性初始化
Field Initial
普通方法块初始化
Field Patch Initial
构造函数初始化
Structure Initial 
  • 包含父类
    1. 父类静态变量
    2. 父类静态代码块
    3. 子类静态变量
    4. 子类静态代码块
    5. 父类普通变量
    6. 父类普通代码块
    7. 父类构造函数
    8. 子类普通变量
    9. 子类普通代码块
    10. 子类构造函数
  • 抽象的实现子类: 接口 - 抽线类 - 实现类
    1. 接口静态变量
    2. 抽象类静态变量
    3. 抽象类静态代码块
    4. 实现类静态变量
    5. 实习类静态代码块
    6. 抽象类普通变量
    7. 抽象类普通代码块
    8. 抽象类构造函数
    9. 实现类普通变量
    10. 实现类普通代码块
    11. 实现类构造函数

JVM本地方法栈

本地方法(Native Method):非java语言实现的方法。一般为了提高效率和底层连接方便。

当某线程调用本地方法时,会在内存空间里,java栈以外新建一个方法栈,独立于JVM。

JVM堆分配

java的类与数据被存储进堆中,java程序中的所有线程共享该堆。

数组也有一个与它们类相关联的class文件,所有具有相同维度和类型的数组都是同一个类的实例

堆只能被主动新建,不会被主动清理,GC会根据情形判断回收时机。

JVM引用类型

对象的新建是创建实例+引用实例,对象的赋值是引用赋值(并不是值拷贝):两个引用都指向同一个实例对象。

引用在对象中的使用是值得深究的,特别是集合的灵活使用中。

https://www.cnblogs.com/wade-luffy/category/865120.html

你可能感兴趣的:(语言魅力)