发生OOM时JVM会退出吗

程序是否退出和发生 OOM 无关

需要明确,程序是否退出和发生 OOM 无关,而和当前是否还有存活的非守护线程有关。

只要还有运行中的子线程,即使 main 线程结束或异常崩溃了,程序也不会停止。

public class TestThreadRun {private static class MyTask implements Runnable {@Overridepublic void run() {while (true) {System.out.println(String.format("我是子线程【%s】 每秒执行一次", Thread.currentThread().getName()));try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}}}}public static void main(String[] args) {Thread thread = new Thread(new MyTask(), "sub-thread-1");
//        thread.setDaemon(true);thread.start();System.out.println("main 线程结束");throw new RuntimeException("抛个异常");}
}

发生 OOM 时线程及其持有资源发生什么 

当线程创建对象时,如果内存不足,会进行 GC,若GC 后还是内存不足,JVM 就会抛出OutOfMemoryError,如果线程没有处理异常,异常会继续向外层抛出,kill 掉线程,线程本身和其持有的资源就可以被回收了。

OOM 异常只会导致当前线程结束,对其他线程无影响。

后续其他线程再申请内存空间时,可能由于空间不足会发起 GC,然后就能够回收掉被关闭的线程和相关资源。

但是,线程被 kill 掉后,线程持有的资源只是可以被回收了,并不是一定能够回收,如果这些资源被其他线程持有,或者是一些全局变量、静态变量等不容易被 GC 的对象,那么堆内存空间占用依然会比较高。

这时候,其他线程再申请内存时,会继续发生 OOM 直至所有线程都结束,程序退出。

资源可以被回收的情况

public class TestThreadOOM {private static class Task1 implements Runnable {List<byte[]> list = new ArrayList<>(); // 资源与线程绑定@Overridepublic void run() {while (true) {System.out.println(String.format("我是子线程【%s】 每秒创建一些字节数组", Thread.currentThread().getName()));list.add(new byte[1024*1024*5]);try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}}}}private static class Task2 implements Runnable {@Overridepublic void run() {while (true) {System.out.println(String.format("我是子线程【%s】 每秒执行一次", Thread.currentThread().getName()));try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}}}}public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(new Task1(), "thread-1");thread.start();Thread thread2 = new Thread(new Task2(), "thread-2");thread2.start();thread.join();thread2.join();System.out.println("main 线程结束");}
}

资源回收不了的情况

 代码和上面差不多,只是 List 调整为静态变量

public class TestThreadOOM {static List<byte[]> list = new ArrayList<>(); // 使用静态变量 不会被回收private static class Task1 implements Runnable {@Overridepublic void run() {while (true) {System.out.println(String.format("我是子线程【%s】 每秒创建一些字节数组", Thread.currentThread().getName()));list.add(new byte[1024*1024*5]);try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}}}}private static class Task2 implements Runnable {private AtomicInteger i = new AtomicInteger(0);@Overridepublic void run() {while (true) {System.out.println(String.format("我是子线程【%s】 每秒执行一次", Thread.currentThread().getName()));if (i.getAndIncrement() >= 10) { // 确保线程1 oom了byte[] buf = new byte[1024*1024 * 20]; // 申请一些内存}try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}}}}public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(new Task1(), "thread-1");thread.start();Thread thread2 = new Thread(new Task2(), "thread-2");thread2.start();thread.join();thread2.join();try {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(String.format("【%s】申请内存", Thread.currentThread().getName()));byte[] buf = new byte[1024*1024 * 20]; // 申请一些内存System.out.println("main 线程结束");}
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/68970.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

确保网络的安全技术介绍

防火墙技术 防火墙是隔离本地网络与外界网络的一道防御系统。通常用于内部局域网 与外部广域网之间&#xff0c;通过限制外部网络用户以非法手段来访问内部资源&#xff0c;来达到保 护内部网络的安全。根据安全规则&#xff0c;防火墙对任何外部网络访问内部网络的行为进 …

sql:SQL优化知识点记录(十)

&#xff08;1&#xff09;慢查询日志 Group by的优化跟Order by趋同&#xff0c;只是多了一个having 开启慢查询日志&#xff1a; 演示一下慢sql&#xff1a;4秒之后才会出结果 查看一下&#xff1a;下方显示慢查询的sql &#xff08;2&#xff09;批量插入数据脚本 函数和存…

【跟小嘉学 Rust 编程】二十六、Rust的序列化解决方案(Serde)

系列文章目录 【跟小嘉学 Rust 编程】一、Rust 编程基础 【跟小嘉学 Rust 编程】二、Rust 包管理工具使用 【跟小嘉学 Rust 编程】三、Rust 的基本程序概念 【跟小嘉学 Rust 编程】四、理解 Rust 的所有权概念 【跟小嘉学 Rust 编程】五、使用结构体关联结构化数据 【跟小嘉学…

质量属性案例-架构真题(二十一)

试题一 某电子商务公司升级会员与促销管理系统&#xff0c;向用户提交个性化服务&#xff0c;提高用户粘性。在项目建立之初&#xff0c;公司领导人一致认为目标是提升会员管理方式的灵活性&#xff0c;由于当前用户规模不大&#xff0c;用户简单&#xff0c;系统方面不需要做…

聊聊如何玩转spring-boot-admin

前言 1、何为spring-boot-admin&#xff1f; Spring Boot Admin 是一个监控工具&#xff0c;旨在以良好且易于访问的方式可视化 Spring Boot Actuators 提供的信息 快速开始 如何搭建spring-boot-admin-server 1、在服务端项目的POM引入相应的GAV <dependency><grou…

图神经网络和分子表征:4. PAINN

如果说 SchNet 带来了【3D】的火种&#xff0c;DimeNet 燃起了【几何】的火苗&#xff0c;那么 PAINN 则以星火燎原之势跨入 【等变】时代。 在 上一节 中&#xff0c;我们提到&#xff0c; PAINN 在看到 DimeNet 取得的成就之后&#xff0c;从另一个角度解决了三体几何问题&a…

无涯教程-Android - 系统架构

Android操作系统是一堆软件组件&#xff0c;大致分为五个部分和四个主要层&#xff0c;如体系结构图中所示。 Linux内核 底层是Linux-Linux 3.6&#xff0c;带有大约115个补丁&#xff0c;这在设备硬件之间提供了一定程度的抽象&#xff0c;并且包含所有必需的硬件驱动程序&am…

RK3568开发笔记(六):开发板烧写ubuntu固件(支持mipi屏镜像+支持hdmi屏镜像)

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/132686096 红胖子网络科技博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬…

Sentinel 流量控制框架

1. Sentinel 是什么&#xff1f; Sentinel是由阿里中间件团队开源的&#xff0c;面向分布式服务架构的轻量级高可用流量控制组件。 2. 主要优势和特性 轻量级&#xff0c;核心库无多余依赖&#xff0c;性能损耗小。 方便接入&#xff0c;开源生态广泛。 丰富的流量控制场景。 …

AI篇-chatgpt基本用法(文心一言也适用)

目录 &#xff08;1&#xff09;基本规则 &#xff08;2&#xff09;例子1-文章摘要 &#xff08;3&#xff09;例子2-代码生成 &#xff08;4&#xff09;文心一言链接 &#xff08;1&#xff09;基本规则 相比于搜索引擎&#xff0c;ChatGPT的优势在于其高效的想法关联和…

《CTFshow-Web入门》09. Web 81~90

Web 入门 索引web81题解 web82题解原理 web83题解 web84题解 web85题解 web86题解 web87题解原理 web88题解 web89题解 web90题解 ctf - web入门 索引 web81&#xff1a;include() 利用&#xff0c;一句话木马之 Nginx 日志利用。web82~86&#xff1a;include() 利用&#xff…

WebSocket--技术文档--基本概念--《快速了解WebSocket协议》

阿丹&#xff1a; 不断学习新技术&#xff0c;丰富自己了解更多才能扩展更多世界可能。 官网 WebSocket首页、文档和下载 - HTML5开发相关 - OSCHINA - 中文开源技术交流社区 软件简介 WebSocket 是 HTML5 开始提供的一种浏览器与服务器间进行全双工通讯的网络技术。 WebS…

力扣|找出和所对应的两数的下标

从零开始刷力扣&#xff08;bushi 题目放在这&#xff1a; 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出和为目标值target的两个整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一…

linux上vscode中.cpp文件中引入头文件.hpp时报错:找不到头文件(启用错误钵形曲线)

当在.cpp文件中引入系统给定的头文件时&#xff1a;#include < iostream > 或者引入自定义的头文件 &#xff1a;#include <success.hpp> 报错&#xff1a;找不到相应的头文件&#xff0c;即在引入头文件的改行底下标出红波浪线 解决方法为&#xff1a; &#…

kvm 虚拟化(修改root密码)

安装libguestfs-tools yum install libguestfs-tools 生成新的密码串 # openssl是一个加密工具&#xff0c;-1 是指普通加密&#xff0c; # hello为key &#xff0c; 123456 才是密码&#xff0c; # 下面就是是生成的密码串&#xff0c;这样我们只要将这些进行对应的替换就可…

vue 防抖与节流用法

一、html <template><button click"getData">获取数据</button> </template>二、JS import { throttle } from "/utils/common"; export default {methods:{getData: throttle(async function(params){console.log(”获取接口数…

音视频 ffmpeg命令参数说明

主要参数&#xff1a; -i 设定输入流 -f 设定输出格式(format) -ss 开始时间 -t 时间长度 音频参数&#xff1a; -aframes 设置要输出的音频帧数 -b:a 音频码率 -ar 设定采样率 -ac 设定声音的Channel数 -acodec 设定声音编解码器&#xff0c;如果用copy表示原始编解码数据必须…

【面试精品】关于面试会遇到的Apache相关的面试题

1. Apache HTTP Server 基于什么协议提供网页浏览服务&#xff1f; 答&#xff1a;基于标准的http网络协议提供网页浏览服务。 2. 简述编译安装httpd软件包的基本过程&#xff1f; 答&#xff1a;解包&#xff0c;配置&#xff0c;编译&#xff0c;安装。 3. 编译安装httpd软…

linux入门---动静态库的加载

目录标题 为什么会有动态库和静态库静态库的实现动态库的实现动静态库的加载 为什么会有动态库和静态库 我们来模拟一个场景&#xff0c;首先创建两个头文件 根据文件名便可以得知add.h头文件中存放的是加法函数的声明&#xff0c;sub.h头文件中存放的是减法函数的声明&#…

文章预览 安防监控/视频存储/视频汇聚平台EasyCVR播放优化小tips

视频云存储/安防监控EasyCVR视频汇聚平台基于云边端智能协同&#xff0c;可实现视频监控直播、视频轮播、视频录像、云存储、回放与检索、智能告警、服务器集群、语音对讲、云台控制、电子地图、H.265自动转码H.264、平台级联等。为了便于用户二次开发、调用与集成&#xff0c;…