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`对象。
```java
public static void exit(int status) {
        Runtime.getRuntime().exit(status);
    }
```

看`Runtime`的`exit()`方法,里面调用的是`Shutdown.exit(status)`。
```java
    public void exit(int status) {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkExit(status);
        }
        Shutdown.exit(status);
    }
```

我们看`Shutdown`的`exit()`方法,当status不为0的时候,调用的是`halt(status)`。
```java
    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)`,暂停虚拟机进程,退出。
```java
    static void halt(int status) {
        synchronized (haltLock) {
            halt0(status);
        }
    }

    static native void halt0(int status);
```

![image-20201222221827719](https://markdownpicture.oss-cn-qingdao.aliyuncs.com/blog/image-20201222221827719.png)


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

![](https://markdownpicture.oss-cn-qingdao.aliyuncs.com/20210214153127.png)


下面可以测试一下`Runtime`的属性:
```java
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
java.lang.Runtime
maxMemory:  2713
totalMemory:  184
freeMemory:  180
```

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值