七、Java 虚拟机的组成
虚拟机的组成可以简单那划分为 类加载器、执行引擎,以及运行时数据区里面的 堆、方法区、程序计数器、虚拟机栈、本地方法栈 等。
字节码文件
我们编写的 Java 代码在经过编译后就会转换为 Java 虚拟机可以执行的字节码文件,字节码文件中包含了 魔数、编译的版本号、常量池 以及 字节码指令 等;
类加载器
在 Java 中执类初始化时,需要执行 加载、链接 和 初始化 三个阶段,其中类加载器就是在 加载阶段 中用于将本地或网络中的 字节码文件 加载到 Java 虚拟机中的工具。
堆
堆是在 JVM 启动时创建的,是 JVM 运行时数据区中的一块线程共享的内存区域,其内存空间在逻辑上连续,但物理上不一定连接,其主要用于存储 Java 中的 成员变量、类变量 以及 引用类型的局部变量 等。
方法区
方法区是在 JVM 启动时创建的,是 JVM 运行时数据区中的一块线程共享的内存区域,其内存空间在逻辑上连续,但物理上不一定连接,主要用于存储 类信息、方法信息、域信息、JIT代码缓存、运行时常量池。
虚拟机栈
虚拟机栈是 JVM 运行时数据区中的一块线程私有的内存区域,每当我们创建一个 线程 时就会创建一个 虚拟机栈。虚拟机栈主要用于存储线程的 栈帧,每当线程调用方法时就会创建一个栈帧,线程会在栈帧中执行代码计算逻辑,存储计算过程中的中间变量,和方法中的局部变量,当线程调用方法结束后就会使栈帧出栈,销毁栈帧中的数据。
本地方法栈
本地方法栈和虚拟机栈一样,都是用于存储线程执行 方法 时的一些数据,不过虚拟机栈只会在线程调用 Java 中的方法时起作用,而本地方法栈则是线程调用 Native 类型的方法时起作用。
程序计数器
程序计数器是 JVM 运行时数据区中的一块线程私有的内存区域,每当我们创建一个线程时就会创建一个程序计数器,其主要用于记录线程执行到的 字节码位置,这样可以保证线程在获得 CPU 时间片后执行时,能够恢复到正确的执行位置。
八、JVM 的生命周期
JVM 生命周期主要有三个部分,主要是虚拟机 启动、运行 和 退出 几个过程。
启动
Java 虚拟机的启动是通过引导类加载器 (Bootstrap Class Loader) 创建一个初始类 (initial class) 来完成的,这个类是由虚拟机的具体实现指定的。
自定义的类是由系统类加载器加载的。自定义类的顶级父类都是 Object,Object 作为核心 API 中的类,是需要被引导加载器 (bootstrap class loader) 加载的。父类的加载是优先于子类加载的,所以要加载自定义类之前,会就加载 Object 类。
执行
JVM 运行启动以后有一个清晰的任务,那就是说只要执行 Java 程序,Java 程序执行时 JVM 才会运行,Java 程序结束时 JVM 就会停止。
执行一个所谓的 Java 程序的时候,真真正正在执行的是一个叫做 Java 虚拟机的进程。
退出
JVM 在执行过程中,如果遇到以下几种情况就会退出:
① 程序正常执行结束;
② 程序在执行过程中遇到了异常或错误而异常终止;
③ 由于操作系统用现错误而导致 Java 虚拟机进程终止;
④ 某线程调用 Runtime 类或 system 类的 exit 方法,或 Runtime 类的 halt 方法,并且 Java 安全管理器也允许这次 exit 或 halt 操作;
⑤ 除此之外,JNI(Java Native Interface)规范描述了用 JNI Invocation API 来加载或卸载 Java 虚拟机时,Java 虚拟机的退出情况;
本文地址:百科问答频道 https://www.neebe.cn/wenda/936272_3.html,易企推百科一个免费的知识分享平台,本站部分文章来网络分享,本着互联网分享的精神,如有涉及到您的权益,请联系我们删除,谢谢!