9 OOM和JVM退出。OOM后JVM一定会退出吗?

首先我们把两个概念讲清楚

OOM是线程在申请堆内存,发现堆内存空间不足时候抛出的异常。

JVM退出的条件如下:

java虚拟机在没有守护线程的时候会退出。守护线程是启动JVM的线程,服务于用户线程。

我们简单说下守护线程的功能:

1.日志的记录和监控

2.资源的管理和清理

3.定时任务执行

4.后台服务

5.JVM内部服务

更加详细的这里不做熬述

我们知道线程是计算机资源调度的基本单位,我们去观察任何操作系统,都是线程作为资源调度的基本单位,在程序异常退出的时候不会操作系统关闭了。有人会说那我有时候打开应用程序的时候用着用着蓝屏了?那是windows操作系统没处理好一些问题造成的。

同样JVM也是虚拟机,遵从大部分计算机的设计理念,java的设计线程的时候也充分考虑了线程的独立性。

所以在未捕获异常的情况下,OOM是该线程异常中止执行,JVM并不会异常退出。这两个算是两个不同的操作,没有必然的联系。

有人会说,那为什么我写一个让JVM OOM的程序,触发之后JVM就退出了呢?那是因为我们在main函数执行的主线程中触发的OOM,线程退出就是main函数退出,当然JVM在main函数退出之后,做完相关的处理之后JVM接着退出了。

我们现在做个总结:

在我们在main函数内部启动的线程发生OOM的时候该线程退出,线程池OOM线程池创建的线程结束。要主线程无关,并且JVM不会退出

什么时候OOMJVM会退出呢?

1:所有的非守护线程由于申请不到内存而OOM,所有非守护线程退出,JVM退出,这个属于主动退出

OOM的发生表示了此刻JVM堆内存告罄,不能分配出更多的资源,或者GC回收效率不可观。

一个线程的OOM,在一定程度的并发下,若此时其他线程(含非守护线程)也需要申请堆内存,那么其他线程也会因为申请不到内存而OOM,甚至连锁反应导致整个JVM的退出

2:OOM溢出,说明内存耗尽,如果操作系统内存耗尽,就会发生OOM killer(Out OfMemory killer),干掉JVM进程,导致被动退出

Linux 内核有个机制叫OOM killer(Out Of Memory killer),该机制会监控那些占用内存过大,尤其是瞬间占用内存很快的进程,然后防止内存耗尽而自动把该进程杀掉。内核检测到系统内存不足、挑选并杀掉某个进程的过程可以参考内核源代码linux/mm/oom_kill.c,当系统内存不足的时候,out_of_memory()被触发,然后调用select_bad_process()选择一个"bad"进程杀掉。如何判断和选择一个"bad进程呢?linux选择"bad"进程是通过调用oom_badness(),挑选的算法和想法都很简单很朴实:最bad的那个进程就是那个最占用内存的进程

相关推荐
用户094248568036 小时前
第18章:ConcurrentHashMap与并发容器实战
java·jvm
一条破秋裤10 小时前
Linux 线程分离与主动取消:pthread_detach、pthread_cancel
java·linux·jvm
bksczm13 小时前
零基础面试题1
jvm·数据结构·算法
今天的砖头有点烫手啊14 小时前
GC 算法与垃圾收集器演进:从 Serial 到 ZGC
java·jvm
johnny23315 小时前
JVM生态下Web开发框架:SparkJava、Javalin、Micronaut、SparkKotlin
jvm
晨小安1 天前
ThreadLocal及其内存泄漏问题深度解析
java·jvm·tomcat·哈希表
jingli91 天前
一个测试用例把连接池卡死 30 秒:SQLite 连接池 max_size=1 下的重入自锁复盘
jvm·sqlite·测试用例
imDwAaY2 天前
Java中垃圾回收器 G1 和 CMS 有什么区别?
jvm·后端
xiaoqiMikko2 天前
JVM 线上排查实战(五):升 JDK 17 后进程起不来,十几个老 GC 参数挨个实测(完结)
java·jvm
Flynt2 天前
Java 27 悄悄改了 3 个默认值,我在 1 核小机器上逐个验证了一遍
java·jvm·性能优化