36-Java程序员的梦魇:OOM内存溢出!

简介: 作为一名Java程序员,平时在公司拼命加班、任劳任怨干活,好不容易熬夜开发完系统,测试完毕,Bug修复完毕,然后上线部署系统,系统开始正常运行,终于歇口气能好好放松下,喝杯Java压压惊了,But!上线后最害怕的事是什么?

前言:

作为一名Java程序员,平时在公司拼命加班、任劳任怨干活,好不容易熬夜开发完系统,测试完毕,Bug修复完毕,然后上线部署系统,系统开始正常运行,终于歇口气能好好放松下,喝杯Java压压惊了,But!上线后最害怕的事是什么?

不用多说,相信大家应该猜到了,一定是事故!很多大公司叫 Case,一旦当系统出现 Case,比如线上核心系统突然宕机不可用,导致几个小时内用户无法下单,进而导致公司损失几百万,甚至几千万;或者公司的某个单点登录系统突然不可用,导致所有用户无法登录APP,也无法下单;或者公司的缓存集群突然全面故障,进而导致公司的全部系统一起瘫痪!或者因为某个明星的突然出轨,结果导致流量集中访问某台服务器,直接把数据库搞挂!

凡是以上种种,都可以称作为:重大Case!一旦有Case,就会有程序员被拉出去祭天,当然这也是网上常见的一个段子(开个玩笑)。

针对这些事故,肯定是需要有人去承担的,重要的是分析到底什么原因导致的事故,谁的责任,后续如何优化以及避免!

那么作为Java程序员而言,先不考虑自己系统外部依赖的缓存、消息队列、数据库等等东西挂掉,就我们自己系统本身而言,最常见的挂掉原因是什么呢?

答案:没错!就是系统OOM(Out Of Memory),也就是所谓的内存溢出!

为什么会出现OOM?

通过之前JVM的一系列学习,相信大家对于JVM内存结构,内存分配,运行原理已经了解的非常清楚了,那么为什么系统会发生OOM呢?

首先给出官方的一段解释:

Thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector.

意思就是说,当JVM因为没有足够的内存来为对象分配空间并且垃圾回收器也已经没有空间可回收时,就会抛出这个error(注:非exception,因为这个问题已经严重到不足以被应用处理)。

为什么会没有内存了呢?原因不外乎有两点:

1)分配的少了:比如虚拟机本身可使用的内存(一般通过启动时的VM参数指定)太少。

2)应用用的太多,并且用完没释放,浪费了。此时就会造成内存泄露或者内存溢出。

内存泄露:申请使用完的内存没有释放,导致虚拟机不能再次使用该内存,此时这段内存就泄露了,因为申请者不用了,而又不能被虚拟机分配给别人用。

内存溢出:申请的内存超出了JVM能提供的内存大小,此时称之为溢出。

在之前没有垃圾自动回收的日子里,比如C语言和C++语言,我们必须亲自负责内存的申请与释放操作,如果申请了内存,用完后又忘记了释放,比如C++中的new了但是没有delete,那么就可能造成内存泄露。偶尔的内存泄露可能不会造成问题,而大量的内存泄露可能会导致内存溢出。

而在Java语言中,由于存在了垃圾自动回收机制,所以,我们一般不用去主动释放不用的对象所占的内存,也就是理论上来说,是不会存在“内存泄露”的。但是,如果编码不当,比如,将某个对象的引用放到了全局的Map中,虽然方法结束了,但是由于垃圾回收器会根据对象的引用情况来回收内存,导致该对象不能被及时的回收。如果该种情况出现次数多了,就会导致内存溢出,比如系统中经常使用的缓存机制。Java中的内存泄露,不同于C++中的忘了delete,往往是逻辑上的原因泄露。

其实简单总结一下Java系统为什么发生OOM:不外乎就是不停的往JVM内存中扔东西,导致最终没有足够的内存可以容纳,如下图所示:

一旦系统不停的往内存中大量塞东西,导致JVM内存撑爆,直接OOM,系统瘫痪,那么对于我们来说是致命的打击,直接导致我们的系统停止运转,甚至JVM进程直接崩溃,进程都没了。用户点击APP,网页都没反应。对于程序员的我们来讲可能辛苦开发了几个月的绩效奖金不但拿不到,反而被扣绩效,甚至年终奖也没了。。。弄不好今年还得提前出去找工作了

如何处理OOM呢?

其实最可怕的并不是线上系统发生OOM,最可怕的是很多工程师压根儿就没有这种处理线上系统故障的经验!

当发生OOM之后,根本不知道系统为什么会突然OOM?到底产生了多少对象,为什么会产生这些对象,到底是哪些对象,内存到底分配了多大,如何去排查这个问题,如何解决,一切皆是迷!

我不听,我不听,这肯定不关我的事儿!一定不是我的代码导致的。这是不是你的内心第一想法?

接下来OpenCoder将为大家带来针对各种可能发生OOM的情况,结合内存溢出的一些场景,通过模拟代码真实感受以及如何解决OOM带来的问题,给到大家如何去监控、定位、排查、分析和解决JVM OOM的问题,再也无惧线上系统突然出现的OOM状况!

目录
相关文章
|
14天前
|
存储 Java 编译器
Java内存模型(JMM)深度解析####
本文深入探讨了Java内存模型(JMM)的工作原理,旨在帮助开发者理解多线程环境下并发编程的挑战与解决方案。通过剖析JVM如何管理线程间的数据可见性、原子性和有序性问题,本文将揭示synchronized关键字背后的机制,并介绍volatile关键字和final关键字在保证变量同步与不可变性方面的作用。同时,文章还将讨论现代Java并发工具类如java.util.concurrent包中的核心组件,以及它们如何简化高效并发程序的设计。无论你是初学者还是有经验的开发者,本文都将为你提供宝贵的见解,助你在Java并发编程领域更进一步。 ####
|
19天前
|
Java 程序员
JAVA程序员的进阶之路:掌握URL与URLConnection,轻松玩转网络资源!
在Java编程中,网络资源的获取与处理至关重要。本文介绍了如何使用URL与URLConnection高效、准确地获取网络资源。首先,通过`java.net.URL`类定位网络资源;其次,利用`URLConnection`类实现资源的读取与写入。文章还提供了最佳实践,包括异常处理、连接池、超时设置和请求头与响应头的合理配置,帮助Java程序员提升技能,应对复杂网络编程场景。
44 9
|
25天前
|
缓存 easyexcel Java
Java EasyExcel 导出报内存溢出如何解决
大家好,我是V哥。使用EasyExcel进行大数据量导出时容易导致内存溢出,特别是在导出百万级别的数据时。以下是V哥整理的解决该问题的一些常见方法,包括分批写入、设置合适的JVM内存、减少数据对象的复杂性、关闭自动列宽设置、使用Stream导出以及选择合适的数据导出工具。此外,还介绍了使用Apache POI的SXSSFWorkbook实现百万级别数据量的导出案例,帮助大家更好地应对大数据导出的挑战。欢迎一起讨论!
141 1
|
4天前
|
SQL 存储 Java
面向 Java 程序员的 SQLite 替代品
SQLite 是轻量级数据库,适用于小微型应用,但其对外部数据源支持较弱、无存储过程等问题影响了开发效率。esProc SPL 是一个纯 Java 开发的免费开源工具,支持标准 JDBC 接口,提供丰富的数据源访问、强大的流程控制和高效的数据处理能力,尤其适合 Java 和安卓开发。SPL 代码简洁易懂,支持热切换,可大幅提高开发效率。
|
9天前
|
缓存 算法 Java
本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制
在现代软件开发中,性能优化至关重要。本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制。通过调整垃圾回收器参数、优化堆大小与布局、使用对象池和缓存技术,开发者可显著提升应用性能和稳定性。
30 6
|
13天前
|
存储 缓存 安全
Java内存模型(JMM):深入理解并发编程的基石####
【10月更文挑战第29天】 本文作为一篇技术性文章,旨在深入探讨Java内存模型(JMM)的核心概念、工作原理及其在并发编程中的应用。我们将从JMM的基本定义出发,逐步剖析其如何通过happens-before原则、volatile关键字、synchronized关键字等机制,解决多线程环境下的数据可见性、原子性和有序性问题。不同于常规摘要的简述方式,本摘要将直接概述文章的核心内容,为读者提供一个清晰的学习路径。 ####
35 2
|
14天前
|
存储 安全 Java
什么是 Java 的内存模型?
Java内存模型(Java Memory Model, JMM)是Java虚拟机(JVM)规范的一部分,它定义了一套规则,用于指导Java程序中变量的访问和内存交互方式。
36 1
|
16天前
|
SQL Java 程序员
倍增 Java 程序员的开发效率
应用计算困境:Java 作为主流开发语言,在数据处理方面存在复杂度高的问题,而 SQL 虽然简洁但受限于数据库架构。SPL(Structured Process Language)是一种纯 Java 开发的数据处理语言,结合了 Java 的架构灵活性和 SQL 的简洁性。SPL 提供简洁的语法、完善的计算能力、高效的 IDE、大数据支持、与 Java 应用无缝集成以及开放性和热切换特性,能够大幅提升开发效率和性能。
|
22天前
|
IDE Java 程序员
C++ 程序员的 Java 指南
一个 C++ 程序员自己总结的 Java 学习中应该注意的点。
20 5
|
20天前
|
存储 运维 Java
💻Java零基础:深入了解Java内存机制
【10月更文挑战第18天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
27 1