写点什么

JVM 笔记 -- JVM 的生命周期介绍

发布于: 2021 年 03 月 09 日

Github 仓库地址:https://github.com/Damaer/JvmNote

文档地址:https://damaer.github.io/JvmNote/


JVM 生命周期

  • 启动

  • 执行

  • 退出


启动

Java 虚拟机的启动时通过引导加载器(bootstrap class loader)创建一个初始类(initial class)来完成的,这个类是由 Java 虚拟机的具体实现指定的。


自定义的类是由系统类加载器加载的。自定义类的顶级父类都是ObjectObject作为核心api中的类,是需要被引导加载器(bootstrap class loader)加载的。父类的加载是优先于子类加载的,所以要加载自定义的之前,会就加载Object类。


执行

  • Java虚拟机执行的时候有一个清晰的任务:执行Java程序。

  • 真正执行程序的是一个叫Java虚拟机的进程。


退出

虚拟机的退出有以下几种情况:

  • 程序正常执行结束

  • 程序执行过程中遇到了异常或者错误而异常终止

  • 由于操作系统出现错误而导致 Java 虚拟机进程终止

  • 某线程调用Runtime类或者System类的exit方法,或者Runtime类的halt()方法,并且Java安全管理器也允许这次操作的条件下。

  • JNIjava native Interface):用JNIapi加载或者卸载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);    }
复制代码


Runtimeexit()方法,里面调用的是Shutdown.exit(status)

    public void exit(int status) {        SecurityManager security = System.getSecurityManager();        if (security != null) {            security.checkExit(status);        }        Shutdown.exit(status);    }
复制代码


我们看Shutdownexit()方法,当 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.RuntimemaxMemory:  2713totalMemory:  184freeMemory:  180
复制代码


PS:本笔记是在宋红康老师的 JVM 视频中学习的笔记,均经过实践,加上自己的理解。地址:https://www.bilibili.com/video/BV1PJ411n7xZ ,强烈推荐!!!


【作者简介】

秦怀,公众号【秦怀杂货店】作者,技术之路不在一时,山高水长,纵使缓慢,驰而不息。这个世界希望一切都很快,更快,但是我希望自己能走好每一步,写好每一篇文章,期待和你们一起交流。


发布于: 2021 年 03 月 09 日阅读数: 7
用户头像

纵使缓慢,驰而不息。 2018.05.17 加入

慢慢走,比较快。公众号:秦怀杂货店

评论

发布
暂无评论
JVM笔记 -- JVM的生命周期介绍