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

相关推荐
Greyson15 小时前
Layui表格如何使用第三方插件实现树形展示.txt
jvm·数据库·python
2401_871696525 小时前
mysql行级锁失效的原因排查_检查查询条件与执行计划
jvm·数据库·python
a9511416426 小时前
CSS如何实现元素隐藏不占位_使用display-none完全移除
jvm·数据库·python
m0_493934537 小时前
如何监控AWR数据收集Job_DBA_SCHEDULER_JOBS中的BSLN_MAINTAIN_STATS
jvm·数据库·python
a9511416428 小时前
Go语言如何操作OSS_Go语言阿里云OSS上传教程【完整】
jvm·数据库·python
2401_897190558 小时前
MySQL中如何利用LIMIT配合函数分页_MySQL分页查询优化
jvm·数据库·python
Polar__Star8 小时前
C#怎么使用并发集合 C#ConcurrentDictionary和ConcurrentQueue线程安全集合怎么用【进阶】
jvm·数据库·python
m0_493934539 小时前
Go语言中 & 与 - 的本质区别及指针使用详解
jvm·数据库·python
Greyson19 小时前
Redis如何解决哨兵通知延迟问题_优化客户端连接池动态刷新拓扑的订阅监听机制
jvm·数据库·python
weixin_5806140010 小时前
如何防止SQL注入利用存储过程_确保存储过程不拼字符串.txt
jvm·数据库·python