JVM基本原理

411 阅读2分钟
  • 为什么我们要学习JVM?
    • 学习JVM,能更好的了解程序为什么是这样运作的
    • 能够自定义参数,优化JVM,使得我们的程序在JVM中获得更好的性能
  • 先来看下大致的流程图 JVM.png 首先我们来创建几个用于测试的类
public class A {
    public A() {
        System.out.println("Init A class");
    }
}

public class B extends A {
    public static void main(String[] args) {
        B b = new B();
        C c = new C();
        c.test();
    }
}

public class C {
    public void test() {
        System.out.println("test method");
    }
}
  • 字节码是什么?为什么有字节码
    我们都知道Java是跨平台的,那它为什么能够跨平台,答案就是字节码, 它在操作系统上层封装了JVM,使用的class字节码,对操作系统解耦了。

  • JVM如何使用字节码的
    首先我们编写的x.java文件通过打包或者命令的方式编译成了.class文件, JVM可以通过这些.class文件获取到相关的信息,然后用于程序的执行,默认会找到main方法。

  • JVM加载字节码的过程

    • 加载
      加载是类加载中的一个过程,不是类加载
      通过全限定类名获得二进制流 转化成方法区的运行时数据结构
      生成一个代表这个类的java Class对象,作为方法区这个类的各种数据入口
    • 连接
      • 验证
        校验.class文件是否符合JVM规范,至少它要能被JVM识别才行
      • 准备
        为.class文件分配所需的内存,其程序中的变量都会被初始化为 初始值
      • 解析
        符号引用替换成直接引用
      • 初始化
        如果有父类,会先初始化父类
        会执行static块代码 将程序中的变量,需要真正的赋予值
    • 使用
    • 卸载
  • JVM类加载

    • 什么时候加载(这个类被用到的时候)
    • 类加载器
      • 启动类加载器(BootStrap ClassLoader)
      • 扩展类加载器(Extension ClassLoader)
      • 应用类加载器(Applicaition ClassLoader)
      • 自定义加载器
    • 双亲委派机制
      • 作用(为了保证核心不会被串改,保证同一个文件不会被加载多次)
      • 加载时会向上加载
  • JVM运行时数据区域

    • 方法区(线程共享)
      用于存储类、常量等信息
    • 程序计数器(线程私有) 用于存储当前执行指令位置,线程直接切换之后要知道上次执行到哪里了吧?
    • 虚拟机栈(线程私有)
      存储线程中的局部变量,以及虚拟机方法调用情况,为虚拟机服务
    • 本地方法栈 虚拟机使用的到的Native方法,HotShot将虚拟机栈和本地方法栈合二为一
    • 堆内存
      对象实例开辟的内存空间,对象的实际地址