标题JVM基础知识

一、 JVM基础知识

1、JVM介绍
JVM即Java Virtual Machine,Java虚拟机。JVM是Java的核心和基础,在Java编译器和os平台之间的虚拟处理器。他是一种利用软件方法实现的抽象的计算机基于下层的操作系统和软件平台,可以在上面执行Java的字节码程序。
JVM有自己完善的软件架构,如处理器、堆栈、寄存器,还具有相应的指令系统。Java语言最重要的特点就是跨平台运行,使用JVM就是为了支持与操作系统无关,实现跨平台。

2、JRE/JDK/JVM是什么关系?
JRE是Java的运行环境,也就是Java平台,所有Java程序要在jre下才能运行。
JDK是程序开发者用来编译、调试Java程序用的开发工具包,JDK的工具也是Java程序,也需要JRE才能运行。为了保持JDK的独立性和完整性,在JDK的安装过程中,JRE也是安装的一部分。所以在JDK的安装目录下有一个名为jre的目录,用于存放JRE文件。
JVM是JRE的一部分,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。
JVM 基础知识
3、JVM的生命周期
启动和消亡:
JVM负责运行一个Java程序。当启动一个Java程序时虚拟机也就诞生了。当该程序关闭退出,这个虚拟机实例也就随之消亡。
JVM运行起点:
Java虚拟机实例通过调用某个初始类的main()方法来运行一个Java程序,而这个main()方法必须是共有的(public),静态(static),返回值为void并且接受一个字符串数组作为参数。任何拥有这样一个main()方法的类都可以作为Java程序运行的起点。
JVM两种线程:
守护线程和非守护线程。守护线程通常是由虚拟机自己使用的,比如执行垃圾收集任务的线程。但Java程序也可以把创建的线程标记为守护线程。而Java程序中的初始线程–main()的线程是非守护线程。
只要还有任何非守护线程在运行,那这个Java程序也会继续运行。当该程序中所有的非守护线程都终止时,虚拟机实例将自动退出。假若安全管理允许,程序本身也能够通过调用Runtime类或者System类的exit()方法来退出。

二、JVM的工作过程

1、类的加载机制
Java源文件–>编译器–>字节码文件
字节码文件–>JVM–>机器码
每一种平台的解释器不同,但是实现的虚拟机是相同的,这也是Java为什么能够跨平台的原因,当一个程序从运行开始,这个虚拟机就开始实例化了,多个程序启动就会存在多个虚拟机实例。程序退出或关闭,虚拟机实例就消亡,多个虚拟机实例之间数据不能共享。

2、类的加载过程(其他博客有详细记载)
JVM被划分成三个主要的子系统:类装载子系统、运行时数据区、执行引擎
类加载详细过程
(1)加载,查找并加载类的二进制数据,在Java堆中也创建一个java.lang.Class类的对象。
(2)连接,连接又包含三块内容:验证、准备、初始化。
1)验证:文件格式、元数据、字节码、符号引用验证
2)准备:为类的静态变量分配内存,并将其初始化为默认值
3)解析:把类中的符号引用转换为直接引用
(3)初始化,为类的静态变量赋予正确的初始值

3、类的加载时机
主动初始化的六种方式:
1)创建对象实例:new对象的时候,会对类初始化,前提是这个类没有被初始化。
2)调用类的静态属性或为静态属性赋值。
3)调用类的静态方法
4)通过class文件反射创建对象
5)初始化一个类的子类:使用子类的时候先初始化父类
6)Java虚拟机启动时被标记为启动类的类:比如main方法所在的类
注:Java类的加载是动态的,它并不会一次性将所有类全部加载后再运行,而是保证程序运行的基础类(像是基类)完全加载到JVM中,至于其他类,则在需要的时候才加载,这当然就是为了节省内存开销。
不会进行初始化的情况
1)在同一个类加载器下面只能初始化类一次,如果已经初始化了就不必要初始化了。
2)在编译的时候能够确定下来的静态变量(编译常量),不会对类进行初始化。

4、类加载器
JVM 基础知识
双亲委派模型的工作过程
1)当前类加载器从自己已经加载的类中查询是否此类已经加载,如果已经加载则返回原来已经加载的类。
2)如果没有找到,就去委托父类加载器去加载。父类加载器也会采用同样的方法,查看自己已经加载的类中是否包含此类,有就返回,没有就委托自己的父类去加载,直到委托到启动类加载器为止。如果父类加载器为空,就代表使用启动类加载器作为父类加载器去加载该类
3)如果启动类加载器加载失败,就会使用扩展类加载器来尝试加载,继续失败则会使用AppClassLoader来加载,继续失败就会抛出一个异 常assNotFoundException。
使用双亲委派模型的好处:
1)安全性,避免用户自己编写的类动态替换Java的一些核心类
2)避免类的重复加载。

5、Java内存模型
JVM内存划分:
方法区(线程共享)常量 静态变量 JIT(即使编译器)编译后代码也在方法区存放
堆内存(线程共享)垃圾回收的主要场地
程序计数器 当前线程执行的字节码的位置指示器

相关文章: