JVM笔记 -- JVM的生命周期介绍
Github仓库地址:https://github.com/Damaer/JvmNote
文档地址:https://damaer.github.io/JvmNote/
JVM生命周期
- 启动
- 执行
- 退出
启动
Java虚拟机的启动时通过引导加载器(bootstrap class loader)创建一个初始类(initial class)来完成的,这个类是由Java虚拟机的具体实现指定的。
自定义的类是由系统类加载器加载的。自定义类的顶级父类都是Object,Object作为核心api中的类,是需要被引导加载器(bootstrap class loader)加载的。父类的加载是优先于子类加载的,所以要加载自定义的之前,会就加载Object类。
执行
Java虚拟机执行的时候有一个清晰的任务:执行Java程序。- 真正执行程序的是一个叫
Java虚拟机的进程。
退出
虚拟机的退出有以下几种情况:
- 程序正常执行结束
- 程序执行过程中遇到了异常或者错误而异常终止
- 由于操作系统出现错误而导致Java虚拟机进程终止
- 某线程调用
Runtime类或者System类的exit方法,或者Runtime类的halt()方法,并且Java安全管理器也允许这次操作的条件下。 JNI(java native Interface):用JNI的api加载或者卸载Java虚拟机的时候,Java虚拟机可能异常退出。
System.exit()和Runtime.halt()
下面分析System.exit()和Runtime.halt():
System.exit()其实调用的是Runtime对象的exit()方法,Runtime.getRuntime()获取的是当前的运行时状态,也就是Runtime对象。
public static void exit(int status) {
Runtime.getRuntime().exit(status);
}
看Runtime的exit()方法,里面调用的是Shutdown.exit(status)。
public void exit(int status) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkExit(status);
}
Shutdown.exit(status);
}
我们看Shutdown的exit()方法,当status不为0的时候,调用的是halt(status)。
static void exit(int status) {
boolean runMoreFinalizers = false;
synchronized (lock) {
if (status != 0) runFinalizersOnExit = false;
switch (state) {
case RUNNING: /* Initiate shutdown */
state = HOOKS;
break;
case HOOKS: /* Stall and halt */
break;
case FINALIZERS:
if (status != 0) {
/* Halt immediately on nonzero status */
halt(status);
} else {
/* Compatibility with old behavior:
* Run more finalizers and then halt
*/
runMoreFinalizers = runFinalizersOnExit;
}
break;
}
}
if (runMoreFinalizers) {
runAllFinalizers();
halt(status);
}
synchronized (Shutdown.class) {
/* Synchronize on the class object, causing any other thread
* that attempts to initiate shutdown to stall indefinitely
*/
sequence();
halt(status);
}
}
而halt(int status)本质上调用的是一个本地方法halt0(int status),暂停虚拟机进程,退出。
static void halt(int status) {
synchronized (haltLock) {
halt0(status);
}
}
static native void halt0(int status);

Runtime是运行时数据的对象,全局单例的,可以理解为它代表了运行时数据区。是一个饿汉式单例模式。从 JDK1.0 开始就,可以看出,这就是虚拟机的核心类!

下面可以测试一下Runtime的属性:
public class RuntimeTest {
public static void main(String[] args) {
Runtime runtime = Runtime.getRuntime();
System.out.println(runtime.getClass().getName());
System.out.println("maxMemory: "+runtime.maxMemory()/1024/1024);
System.out.println("totalMemory: "+runtime.totalMemory()/1024/1024);
System.out.println("freeMemory: "+runtime.freeMemory()/1024/1024);
}
}
运行结果:表示最大的内存是2713M,总的内存是184M,可以使用内存是180M。
java.lang.Runtime
maxMemory: 2713
totalMemory: 184
freeMemory: 180
PS:本笔记是在宋红康老师的JVM视频中学习的笔记,均经过实践,加上自己的理解。地址:https://www.bilibili.com/video/BV1PJ411n7xZ ,强烈推荐!!!
【作者简介】:
秦怀,公众号【秦怀杂货店】作者,技术之路不在一时,山高水长,纵使缓慢,驰而不息。这个世界希望一切都很快,更快,但是我希望自己能走好每一步,写好每一篇文章,期待和你们一起交流。
JVM笔记 -- JVM的生命周期介绍的更多相关文章
- MAVEN学习笔记之Maven生命周期和插件简介(3)
MAVEN学习笔记之Maven生命周期和插件简介(3) clean compile site三套生命周期相互独立. clean pre-clean 执行清理前的工作 clean 清理上一次构建生成的所 ...
- JVM中的对象生命周期
在JVM运行空间中,对象的整个生命周期大致可以分为七个阶段:创建阶段(Creation).应用阶段(Using).不可视阶段(Invisible).不可到达阶段( Unreachable).可收集阶段 ...
- JVM:类的生命周期
类的生命周期 综述 1. 只有当一个类被切实使用到的时候才会被加载到虚拟机中(例如:new, 方法调用, A a = null;不算) 2. 若在加载一个类的过程中,有其他类被切实使用到, ...
- jvm与程序的生命周期
yls 2019/11/5 java虚拟机结束生命周期的情况: 执行了System.exit(); 程序正常运行结束 程序在执行过程中遇到异常或错误而异常终止 由于操作系统出现错误而导致jvm进程终止 ...
- Maven学习笔记(六):生命周期与插件
何为生命周期: Maven的生命周期就是为了对全部的构建过程进行抽象和统一.Maven从大量项目和构建工具中学习和反思,然后总结了一套高度完好的.易扩展的生命周期.这个生命周期包括了项目的清 ...
- JVM笔记 -- JVM经历了什么?
Sun Classic VM 世界上第一款商用 Java 虚拟机,JDK1.4 已经淘汰. 内部只有解释器,可以自己外挂JIT编译器,但是二者只能使用其一,不能配合工作. hotspot 内置了该虚拟 ...
- IOS学习笔记37——ViewController生命周期详解
在我之前的学习笔记中讨论过ViewController,过了这么久,对它也有了新的认识和体会,ViewController是我们在开发过程中碰到最多的朋友,今天就来好好认识一下它.ViewContro ...
- Android笔记——活动的生命周期
一.活动的重要性 掌握活动的生命周期对任何 Android 开发者来说都非常重要,当你深入理解活动的生命周期之后,就可以写出更加连贯流畅的程序,并在如何合理管理应用资源方面,你会发挥的游刃有余.你的应 ...
- Android之Fragment学习笔记②(Fragment生命周期)
一. Fragment生命周期图 二.Fragment生命周期方法介绍 Fragment的生命周期和activity生命周期很像,其生 ...
随机推荐
- AtCoder Beginner Contest 173 C - H and V (二进制枚举)
题意:有一张图,.表示白色,#表示黑色,每次可以将多行和多列涂成红色(也可不涂),问有多少种方案,使得剩下黑点的个数为\(k\). 题解:又学到了新的算法qwq,因为这题的数据范围很小,所以可以用二进 ...
- Python 装包与拆包
装包就是把未命名的参数放到元组中,把命名参数放到字典中 a = 1, 2 print(a) (1, 2) 拆包将一个结构中的数据拆分为多个单独变量中 *args **kwargs def run1(* ...
- .NET并发编程-函数闭包
本系列学习在.NET中的并发并行编程模式,实战技巧 内容目录 函数式编程闭包的应用记忆化函数缓存 函数式编程 一个函数输出当做另一个函数输入.有时候一个复杂问题,我们拆分成很多个步骤函数,这些函数组合 ...
- pip&conda 换源
PIP 各种可用源 清华源:https://pypi.tuna.tsinghua.edu.cn/simple 临时指定源 pip install -i https://pypi.tuna.tsingh ...
- codeforces 869A
A. The Artful Expedient time limit per test 1 second memory limit per test 256 megabytes input stand ...
- SPOJ - LCS2 Longest Common Substring II(后缀自动机)题解
题意: 求\(n\)个串的最大\(LCS\). 思路: 把第一个串建后缀自动机,然后枚举所有串.对于每个串,求出这个串在\(i\)节点的最大匹配为\(temp[i]\)(当前串在这个节点最多取多少), ...
- μC/OS-III---I笔记6---互斥信号量
互斥信号量 操作系统中利用信号量解决进程间的同步和互斥(互斥信号量)的问题,在多道程序环境下,操作系统就是遮掩实现进程之间的同步和互斥.但是在使用的过程中厉害的前辈还是发现了这一优秀机制的缺陷,它会导 ...
- MBP 屏幕分辨率 All In One
MBP 屏幕分辨率 All In One screen size bug https://stackoverflow.com/questions/65462643/how-to-get-the-rea ...
- ES-Next @Decorator All In One
ES-Next @Decorator All In One @装饰器 import { logged } from "./logged.mjs"; class C { @logge ...
- HTML5 QRCode Scaner
HTML5 QRCode Scaner how to scan QR Code using the camera of the phone or website live demo https://c ...