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的那个进程就是那个最占用内存的进程

相关推荐
没有bug.的程序员12 小时前
Async Profiler:最精准的火焰图工具
java·jvm·spring·对象分配·async profiler
小帅学编程12 小时前
JVM学习记录
jvm·学习
Yweir12 小时前
Linux性能监控的工具集和分析命令工具
java·linux·jvm
友莘居士13 小时前
深入浅出:以太坊虚拟机(EVM)存储模型设计与权衡
jvm·区块链·虚拟机·solidity·evm·合约调用
找不到、了14 小时前
栈帧四要素:JVM 方法执行的完整上下文
java·jvm
TroubleBoy丶15 小时前
Docker可用镜像
java·linux·jvm·docker
Zzzzzxl_15 小时前
互联网大厂Java/Agent面试实战:Spring Boot、JVM、微服务与AI Agent/RAG场景问答
java·jvm·spring boot·ai·agent·rag·microservices
未若君雅裁15 小时前
JVM高级篇总结笔记
java·jvm·笔记
Zzzzzxl_16 小时前
互联网大厂Java/Agent面试实战:JVM、Spring Boot、微服务与RAG全栈问答
java·jvm·springboot·agent·rag·microservices·vectordb
Zzzzzxl_16 小时前
互联网大厂Java/Agent面试实战:微服务、RAG与Agent化实战(含答疑解析)
java·jvm·spring boot·agent·milvus·rag·microservices