什么是虚拟机?
虚拟机本质上是一种软件。大致可分为系统虚拟机(仿真物理机)和程序虚拟机(执行单个计算机程序,比如JVM)。
什么是Java虚拟机?
执行Java应用的字节码,并且把字节码转化到硬件,操作系统的指令。历经时间的迭代,目前广泛应用的Java虚拟机是Oracle的HotSpot VM。
堆与栈是个什么东东?
栈是运行时的单位,而堆是存储的单位。
栈解决程序的运行问题,即程序如何执行,或者说如何处理数据;堆解决的是数据存储的问题,即数据怎么放、放在哪儿。
堆中存的是对象。栈中存的是基本数据类型和堆中对象的引用。
JVM如何实现平台无关性?
JVM内存结构
线程共享:Java堆,方法区
线程私有:程序计数器,Java栈,本地方法栈
-
程序计数器(线程私有):每个线程都有一个程序计数器,就是一个指针,指向方法区中的方法字节码(下一个将要执行的指令代码),由执行引擎读取下一条指令
-
Java栈(线程私有):一个线程对应一个java栈,每执行一个方法就会往栈中压入一个元素,这个元素叫“栈帧”,而栈帧中包括了方法中的局部变量。
-
本地方法栈(线程私有):调用本地方法库,实现与操作系统、硬件交互的目的。
-
Java堆(线程共享):存放Java程序的实例对象
-
方法区(线程共享):存放程序类的元数据
类的元数据:
- 类的类型信息:类的全名,父类的全名,类型修饰符(public,private),直接接口类表
- 常量池:类方法,域引用的常量
- 域信息:域名称,域类型,域修饰符
- 方法信息:方法名,返回类型,方法参数,方法修饰符
JVM类加载机制
JVM 虚拟机执行 class 字节码的过程的关键步骤:加载、验证、准备、初始化、卸载。
加载:将代码数据加载到内存中。
验证:对字节码流进行校验,判断是否符合JVM规范。
准备:(重点)
- 为类变量分配内存。类变量(被static修饰的变量)
- 初始化:为类成员变量(非static)分配内存【赋予 Java 语言中该数据类型的零值】。如果变量被static final修饰,则直接赋值。
初始化:JVM 会根据语句执行顺序对类对象进行初始化
- 当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化。
- 当虚拟机启动时,用户需要指定一个要执行的主类(包含main()方法的那个类),虚拟机会先初始化这个主类。(main所在类)
类的初始化顺序
Java代码编译成字节码文件之后,执行类初始化方法和对象初始化方法。
类初始化方法:编译器会按照其出现顺序,收集类变量的赋值语句、静态代码块,最终组成类初始化方法。
(在类初始化时执行)
对象初始化方法:编译器会按照其出现顺序,收集成员变量的赋值语句、普通代码块,最后收集构造函数的代码,最终组成对象初始化方法。(在实例化对象时执行)
总结
- 1.类变量(static)初始化
- 2.初始化入口方法(main) static Book book = new Book();会先触发对象构造器
- 3.类构造器(类变量的赋值语句、静态代码块)
- 4.对象构造器(成员变量的赋值语句、普通代码块,最后收集构造方法)
参考:JVM 类加载机制(有详细例题)