发生OOM时JVM会退出吗

news2024/12/23 22:59:19

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

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

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

public class TestThreadRun {
    private static class MyTask implements Runnable {
 
        @Override
        public 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<>(); // 资源与线程绑定
        @Override
        public 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 {
        @Override
        public 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 {
 
        @Override
        public 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);
        @Override
        public 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.coloradmin.cn/o/970819.html

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

相关文章

管理类联考——逻辑——汇总篇——知识点突破——论证逻辑——论证模型

不同的模型对应的削弱、支持、假设。 归纳模型 模型识别 1.完全归纳 完全归纳指的就是所谓的穷举法&#xff0c;即通过某一类对象中的全部元素具备或者不具备某个性质&#xff0c;从而证明这一类对象都具备或者不具备某个性质。考试中一般不考察完全归纳&#xff0c;因此&am…

彻底了解 npm、cnpm、pnpm 、yarn几种包管理工具

npm、cnpm、pnpm 、yarn几种包管理工具 npmcnpmyarnpnpm四者的优缺点&#xff1a; npm npm 是 Node.js 自带的包管理器&#xff0c;平时通过 npm install 命令来安装各种 npm 包&#xff08;比如&#xff1a;npm install vue-router &#xff09;&#xff0c;就是通过这个包管…

基于OpenEuler的信创国产瘦客户机软件系统 DoraOS

DoraOS是一款瘦客户机系统软件&#xff0c;最新版本基于OpenEuler开发。可以将主机转化为专业的瘦客户机。目前支持x86架构的硬件。 软件下载地址为&#xff1a; https://www.doracloud.cn/downloads/32-cn.html 制作一张启动U盘&#xff0c;即可进行安装。 DoraOS的连接窗口…

3D数据导出工具HOOPS Publish:3D数据查看、生成标准PDF或HTML文档!

HOOPS中文网http://techsoft3d.evget.com/ 一、3D导出SDK HOOPS Publish是一款功能强大的SDK&#xff0c;可以创作丰富的工程数据并将模型文件导出为各种行业标准格式&#xff0c;包括PDF、STEP、JT和3MF。HOOPS Publish核心的3D数据模型是经过ISO认证的PRC格式(ISO 14739-1:…

【UIPickerView案例04-随机点餐完善 Objective-C语言】

一、之前我们讲到哪里 1)首先,是搭建界面 2)然后呢,是加载数据 先把这个数据文件,拖进来,然后呢,设置它的代理对象、数据源对象 然后呢,在控制器里面,遵守对应的协议, 实现对应的方法 跟TableView的思路,一样一样的, 也是,把多少行返回 把多少组,返回 然后呢…

【python爬虫】12.建立你的爬虫大军

文章目录 前言协程是什么多协程的用法gevent库queue模块 拓展复习复习 前言 照旧来回顾上一关的知识点&#xff01;上一关我们学习如何将爬虫的结果发送邮件&#xff0c;和定时执行爬虫。 关于邮件&#xff0c;它是这样一种流程&#xff1a; 我们要用到的模块是smtplib和emai…

WordPress Page Builder KingComposer 2.9.6 Open Redirection

WordPress Page Builder KingComposer 2.9.6 Open Redirection WordPress 插件 KingComposer 版本2.9.6 以及以前版本受到开放重定向漏洞的影响。该漏洞在packetstorm网站披露于2023年7月24日&#xff0c;除了该漏洞&#xff0c;该版本的插件还存在XSS攻击的漏洞风险 图1.来自…

【无源谐波滤波器通常用于电力系统中的谐波抑制】用于抑制电力系统谐波的无源谐波滤波器(Simulink实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

十年AI技术成果加持,猿辅导带你体验网课中的科技感

近年来&#xff0c;AI正以润物细无声的方式重塑多个行业的面貌&#xff0c;教育行业也不例外。同时&#xff0c;随着Chat GPT对社会带来的冲击不断加强&#xff0c;AI教育已经成为整个行业不可逆转的趋势。作为最早踏入智能教育领域的企业之一&#xff0c;猿辅导深谙技术革新对…

揭秘大企业的在线帮助中心搭建都有什么技巧?

大企业的在线帮助中心是为了提供更好的客户支持和服务而设立的一个重要平台。一个优秀的在线帮助中心可以帮助企业有效地解决客户问题、提高客户满意度&#xff0c;并且节省人力资源。 搭建大企业在线帮助中心的技巧&#xff1a; 设计用户友好的界面&#xff1a;在线帮助中心…

OPPO手机便签数据搬家到华为mate60Pro手机怎么操作

今年8月底&#xff0c;华为上线了本年度的旗舰手机——华为mate60Pro。有不少网友都在抢购这台手机&#xff0c;不过在拿到新手机之后&#xff0c;还有一件重要的事情要做&#xff0c;这就是把旧手机中比较重要的数据&#xff0c;例如图片、短信、通讯录、联系人、便签等数据搬…

13 PyQt5控件之QTreeWidget

目录 1 官方帮助文档2 基本使用3 模型事件 1 官方帮助文档 QTreeWidget Qt5.15帮助文档 2 基本使用 #!/usr/bin/python3 # -*- coding: GBK -*-import sys from PyQt5.QtCore import QSize from PyQt5.QtGui import QIcon from PyQt5.QtWidgets import *class QTreeWidgetDe…

计算机毕设之基于python+django+mysql数据可视化的智慧社区内网平台(包含文档+源码+部署教程)

系统阐述的是一款基于数据可视化的智慧社区内网平台的设计与实现&#xff0c;对于Python、B/S结构、MySql进行了较为深入的学习与应用。主要针对系统的设计&#xff0c;描述&#xff0c;实现和分析与测试方面来表明开发的过程。开发中使用了 django框架和MySql数据库技术搭建系…

xxl-job 任务调度搭建及简单使用

xxl-job是开源架构&#xff0c;可以通过它实现调度中心和执行器。 git地址和 官网中进行了详细的技术说明。   xxl-job支持单机部署和集群式部署&#xff0c;在集群式部署中又可以实现调度中心集群式部署和执行器集群式部署。本文主要针对调度中心和执行器分离单机部署方式进…

因为axios请求后端,接收不到token的问引出的问题

vue axios请求后端接受不到token的问题。 相关概念 什么是跨域&#xff1f; 跨域指的是在浏览器环境下&#xff0c;当发起请求的域&#xff08;或者网站&#xff09;与请求的资源所在的域之间存在协议、主机或端口中的任何一个条件不同的情况。换句话说&#xff0c;只要协议、…

java八股文面试[JVM]——如何打破双亲委派模型

双亲委派模型的第一次“被破坏”是重写自定义加载器的loadClass(),jdk不推荐。一般都只是重写findClass()&#xff0c;这样可以保持双亲委派机制.而loadClass方法加载规则由自己定义&#xff0c;就可以随心所欲的加载类&#xff0c;典型的打破双亲委派模型的框架和中间件有tomc…

基于Java的ssm高校教学业绩信息管理系统源码和论文

基于Java的ssm高校教学业绩信息管理系统源码和论文122 开发工具&#xff1a;idea 数据库mysql5.7 数据库链接工具&#xff1a;navcat,小海豚等 技术&#xff1a;ssm 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存…

如何使用Windows Xshell连接另外一台主机上的虚拟机解决方案

前言 我需要使用我自己的笔记本打开虚拟机服务&#xff0c;如何使用我的台式电脑进行服务访问 环境&#xff1a; 台式&#xff1a;Windows10 笔记本&#xff1a;Windows10 网络是由笔记本开放热点&#xff0c;在同一局域网下 正文 首先我们先要看&#xff0c;我们所需要的虚拟…

Python中重要的条件语句教程

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 一. 了解条件语句 假设一个场景&#xff1a; 同学们这个年龄去过网吧吗&#xff1f; 去网吧进门想要上网必须做的一件事是做什么&#xff1f;&#xff08;考虑重点&#xff09; 为什么要把身份证给工作人员&#xf…

【广州华锐互动】利用AR远程指导系统进行机械故障排查,实现远程虚拟信息互动

随着工业自动化和智能化的不断发展&#xff0c;机械故障诊断已经成为了工业生产中的重要环节。为了提高故障诊断的准确性和效率&#xff0c;近年来&#xff0c;AR&#xff08;增强现实&#xff09;远程协助技术逐渐应用于机械故障诊断领域。本文将探讨AR远程协助技术在机械故障…