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生命周期很像,其生 ...
随机推荐
- Cobalt Strike特征隐藏
前言 首先红蓝对抗的时候,如果未修改CS特征.容易被蓝队溯源. 前段时间360公布了cobalt strike stage uri的特征,并且紧接着nmap扫描插件也发布了.虽说这个特征很早就被发现了 ...
- Kubernetes部署Prometheus+Grafana(非存储持久化方式部署)
1.在master节点处新建一个文件夹,用于保存下载prometheus+granfana的yaml文件 mkdir /root/prometheus cd /root/prometheus git ...
- 牛年 dotnet云原生技术趋势
首先祝大家:新年快乐,牛年大吉,牛年发发发! 2020年的春节,新冠疫情使得全球业务停滞不前,那时候,没有人知道会发生什么,因此会议被取消,合同被搁置,项目被推迟,一切似乎都停止了.但是我们却见证了I ...
- 痞子衡嵌入式:超级下载算法(RT-UFL)开发笔记(4) - 轮询Flash配置参数
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是超级下载算法开发笔记(4)之轮询Flash配置参数. 文接上篇 <超级下载算法(RT-UFL)开发笔记(3) - 统一FlexSP ...
- TypeScript & Canvas 实现可视化白板
TypeScript & Canvas 实现可视化白板 https://excalidraw.com/ https://github.com/excalidraw/excalidraw ref ...
- Graphviz - Graph Visualization Software 开源可视化绘图工具(visio 类)
http://www.graphviz.org/Download_windows.php Welcome to Graphviz Available translations: Romanian, ...
- ES-Next @Decorator All In One
ES-Next @Decorator All In One @装饰器 import { logged } from "./logged.mjs"; class C { @logge ...
- why 2020 you should create a new modern website with web fullstack
why 2020 you should create a new modern website with web fullstack Full-Stack Web Development Front- ...
- js 大数计算
js 大数计算 原理 JavaScript 安全整数 是 -253-1 ~ 253-1 ,即: -9007199254740991 ~ 9007199254740991; 换句话说,整数超过这个范围就 ...
- taro taro 多端同步调试
taro 多端同步调试 debug https://nervjs.github.io/taro/docs/envs-debug.html