当前位置: 首页 > news >正文

Java中的内存泄露、内存溢出与栈溢出

内存泄露、内存溢出与栈溢出

  • 1、概述
  • 2、内存泄漏、内存溢出和栈溢出
    • 2.1、内存泄漏
    • 2.2、内存溢出
    • 2.3、栈溢出
  • 2、总结

1、概述

大家好,我是欧阳方超。本次就Java中几个相似而又不同的概念做一下介绍。内存泄漏、内存溢出和栈溢出都是与内存相关的问题,但它们之间有所不同。

2、内存泄漏、内存溢出和栈溢出

我们经常会遇到内存泄漏、内存溢出和栈溢出等问题,这些问题都与内存的使用有关。

2.1、内存泄漏

内存泄漏(memory leak)指的是程序在使用内存时,未将不再使用的内存释放,导致内存不断占用而无法再次使用。内存泄漏的原因可能是程序中存在未释放的资源、对象引用未被清理、内存分配过多等。当程序中存在大量的内存泄漏时,可能会导致系统性能下降、程序崩溃等问题。
解决方法:及时释放不再使用的资源、对象引用,避免内存分配过多,使用内存检测工具进行检测和修复。

2.2、内存溢出

内存溢出(out of memory)指的是程序在运行时,申请的内存空间超过了系统可用的内存空间。内存溢出的原因可能是程序中存在大量的内存泄漏、对象过多、内存分配过多等。当程序中出现内存溢出时,可能会导致程序崩溃、系统异常等问题。
解决方法:及时释放不再使用的资源、对象引用,避免内存分配过多,使用内存检测工具进行检测和修复,增加系统内存等。

注意,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,如果内存泄漏持续发生而又得不到控制的话,无论多少内存,迟早会被耗尽。memory leak会最终会导致out of memory!

既然内存泄漏与内存溢出有关系,我们就用一个例子来验证一下“内存泄漏会导致内存溢出”这一现象,

import java.util.ArrayList;public class Test {public static void main(String[] args) {ArrayList<Integer> integerArrayList = new ArrayList<>();long i = 1;while (true) {integerArrayList.add(1);System.out.println(i + "times");i++;}}
}

在上面的示例代码中,我们创建了一个包含整数的列表,并在一个无限循环中不断向其中添加整数。由于没有终止循环的条件,程序将不断向列表中添加整数,直到内存溢出为止。当内存不再足够容纳更多的整数时,程序将崩溃,并且会抛出一个OutOfMemoryError异常。将上面的程序运行起来,很快就会发生内存溢出的错误(循环进行了70091070次后发生了内存溢出):

70091068times
70091069times
70091070times
Exception in thread "main" java.lang.OutOfMemoryError: Java heap spaceat java.util.Arrays.copyOf(Arrays.java:3210)at java.util.Arrays.copyOf(Arrays.java:3181)at java.util.ArrayList.grow(ArrayList.java:261)at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:235)at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:227)at java.util.ArrayList.add(ArrayList.java:458)

2.3、栈溢出

栈溢出指的是程序在执行过程中,栈空间超过了系统所能支持的范围。栈溢出的原因可能是程序中存在过多的递归调用、方法嵌套过深等。当程序中出现栈溢出时,可能会导致程序崩溃、系统异常等问题。
解决方法:优化递归算法,减少方法的嵌套层数,增加系统栈空间等。
下面是一个使用递归计算阶乘的例子:

public class Test {public static void main(String[] args) {int num = 10; // 需要计算的阶乘long factorial = calcFactorial(num); // 调用递归函数计算阶乘System.out.println(num + "的阶乘是:" + factorial);}public static long calcFactorial(int n) {if (n == 1) { // 递归结束条件return 1;} else {return n * calcFactorial(n - 1); // 递归调用计算阶乘}}
}

在上述代码中,我们定义了一个静态方法calcFactorial,用于递归计算阶乘。如果n等于1,说明阶乘已经计算完成,直接返回1;否则,递归调用calcFactorial(n - 1)计算n - 1的阶乘,然后将结果乘以n,得到n的阶乘。最终,我们在main方法中调用calcFactorial方法计算阶乘,并输出计算结果。

需要注意的是,递归计算阶乘的方法在计算大数阶乘时可能会超出栈的深度限制,导致栈溢出异常。比如我们将上面程序中num的值改为一万,再次运行时立马会发生栈溢出的问题:

Exception in thread "main" java.lang.StackOverflowErrorat Test.calcFactorial(Test.java:12)at Test.calcFactorial(Test.java:15)at Test.calcFactorial(Test.java:15)at Test.calcFactorial(Test.java:15)

在递归时,栈需要保存函数的调用信息,保存的过多的话会导致栈内存不够用,进而发生栈溢出,我们可以将递归实现的阶乘计算优化成循环实现:

public class Factorial {public static void main(String[] args) {int num = 5; // 需要计算的阶乘long factorial = 1; // 阶乘初始值为1for (int i = 1; i <= num; i++) {factorial *= i; // 计算阶乘}System.out.println(num + "的阶乘是:" + factorial);}
}

在上述代码中,我们定义了一个变量num,表示需要计算的阶乘。然后,我们定义了一个long类型的变量factorial,用于存储阶乘的值,初始值为1。接着,我们使用for循环从1到num,每次将当前的i乘到factorial中,最终得到num的阶乘。最后,我们输出计算结果。

需要注意的是,阶乘可能会非常大,超出了long类型的范围,因此在实际应用中需要使用大数类进行计算,以避免计算结果溢出。另外,阶乘的计算也可以使用递归实现,但需要注意递归深度的控制,以避免栈溢出。

2、总结

内存泄漏、内存溢出和栈溢出都是程序中常见的内存问题,它们都会导致程序运行的异常和不稳定。为了避免这些问题,我们需要在编程中注意及时释放不再使用的资源和对象引用,避免内存分配过多,优化算法和代码结构等。同时,我们还可以使用内存检测工具进行检测和修复,在程序开发和测试过程中,及时发现和解决问题,保证程序运行的稳定性和可靠性。
我是欧阳方超,把事情做好了自然就有兴趣了,如果你喜欢我的文章,欢迎点赞、转发、评论加关注。我们下次见。

相关文章:

Java中的内存泄露、内存溢出与栈溢出

内存泄露、内存溢出与栈溢出 1、概述2、内存泄漏、内存溢出和栈溢出2.1、内存泄漏2.2、内存溢出2.3、栈溢出 2、总结 1、概述 大家好&#xff0c;我是欧阳方超。本次就Java中几个相似而又不同的概念做一下介绍。内存泄漏、内存溢出和栈溢出都是与内存相关的问题&#xff0c;但…...

时序预测 | Matlab实现SSA-GRU、GRU麻雀算法优化门控循环单元时间序列预测(含优化前后对比)

时序预测 | Matlab实现SSA-GRU、GRU麻雀算法优化门控循环单元时间序列预测(含优化前后对比) 目录 时序预测 | Matlab实现SSA-GRU、GRU麻雀算法优化门控循环单元时间序列预测(含优化前后对比)预测效果基本介绍程序设计参考资料 预测效果 基本介绍 Matlab实现SSA-GRU、GRU麻雀算法…...

Java+springboot开发的医院HIS信息管理系统实现,系统部署于云端,支持多租户SaaS模式

一、项目技术框架 前端&#xff1a;AngularNginx 后台&#xff1a;JavaSpring&#xff0c;SpringBoot&#xff0c;SpringMVC&#xff0c;SpringSecurity&#xff0c;MyBatisPlus&#xff0c;等 数据库&#xff1a;MySQL MyCat 缓存&#xff1a;RedisJ2Cache 消息队列&…...

【前端面经】Vue-Vue中的 $nextTick 有什么作用?

Vue.js 是一个流行的 JavaScript 框架&#xff0c;它提供了许多实用的功能&#xff0c;其中之一就是 $nextTick 方法。 在 Vue.js 中&#xff0c; $nextTick 方法可以确保我们在更新 DOM 之后再去执行某些操作&#xff0c;从而避免由于 DOM 更新而导致的问题。这个方法非常实用…...

基于STATCOM的风力发电机稳定性问题仿真分析(Simulink)

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

如何写出高质量的代码

背景说明&#xff1a; 你是否曾经为自己写的代码而感到懊恼&#xff1f;你是否想过如何才能写出高质量代码&#xff1f;那就不要错过这个话题&#xff01;在这里&#xff0c;我们可以讨论什么是高质量代码&#xff0c;如何写出高质量代码等问题。无论你是初学者还是资深开发人…...

15.基于主从博弈的智能小区代理商定价策略及电动汽车充电管理

说明书 MATLAB代码&#xff1a;基于主从博弈的智能小区代理商定价策略及电动汽车充电管理 关键词&#xff1a;电动汽车 主从博弈 动态定价 智能小区 充放电优化 参考文档&#xff1a;《基于主从博弈的智能小区代理商定价策略及电动汽车充电管理》基本复现 仿真平台&#…...

ChatGPT实现多语种翻译

语言翻译 多语种翻译是 NLP 领域的经典话题&#xff0c;也是过去很多 AI 研究的热门领域。一般来说&#xff0c;我们认为主流语种的互译一定程度上属于传统 AI 已经能较好完成的任务。比如谷歌翻译所采用的的神经机器翻译(NMT, Neural Machine Translation)技术就一度让世人惊…...

volatile关键字原理的使用介绍和底层原理解析和使用实例

文章目录 volatile关键字原理的使用介绍和底层原理解析和使用实例1. volatile 关键字的作用2. volatile 的底层原理3. volatile 的使用案例4. volatile 的原子性问题5. 如何解决 volatile 的原子性问题6. volatile 的实现原理7. 小结8. volatile的最佳实践9. 案例:使用volatile…...

【软件下载】换新电脑记录下下载的软件时所需地址

1.idea https://www.jetbrains.com/zh-cn/idea/download/other.html 2.oracle官方&#xff08;下载jdk时找的&#xff09; https://www.oracle.com/ 3.jdk8 https://www.oracle.com/java/technologies/downloads/ 下拉找到jdk8 切换windows &#xff08;需要注册个oracle账…...

【10.HTML入门知识-CSS元素定位】

1 标准流&#xff08;Normal Flow&#xff09; 默认情况下&#xff0c;元素都是按照normal flow&#xff08;标准流、常规流、正常流、文档流【document flow】&#xff09;进行排布  从左到右、从上到下按顺序摆放好  默认情况下&#xff0c;互相之间不存在层叠现象 1.1…...

LeetCode_贪心算法_简单_455.分发饼干

目录 1.题目2.思路3.代码实现&#xff08;Java&#xff09; 1.题目 假设你是一位很棒的家长&#xff0c;想要给你的孩子们一些小饼干。但是&#xff0c;每个孩子最多只能给一块饼干。 对每个孩子 i&#xff0c;都有一个胃口值 g[i]&#xff0c;这是能让孩子们满足胃口的饼干的…...

HashMap

目录 HashMap是什么&#xff1f; 为什么要使用HashMap&#xff1f; HashMap存储元素原理&#xff08;put⽅法&#xff09; 扰动函数 前置知识 异或运算 &运算 为什么使用扰动函数 实验验证扰动函数 常见问题 HashMap的默认长度是多少&#xff1f; HashMap是先扩…...

数据结构初阶 —— 树(堆)

目录 一&#xff0c;堆 堆的概念 向下调整法&#xff08;数组&#xff09; 向上调整法&#xff08;数组&#xff09; 堆的创建&#xff08;建堆&#xff09; 堆的实现 一&#xff0c;堆 堆的概念 如有个关键码的集合K{&#xff0c;&#xff0c;&#xff0c;...&#xf…...

一文看懂低代码,5分钟从入门到原理全搞定

全球低代码市场已经走过了近20年&#xff0c;中国低代码市场近5年经历了百花齐放的广泛探索阶段&#xff0c;更旺盛的市场需求逐步在被激发。现在&#xff0c;让我们按下暂停键&#xff0c;看看这些产品给我们呈现了低代码市场一幅怎样的百景图。 低代码平台简介 广义上的低代…...

MetaERP系统主要干什么的,华为自研ERP的路子是否可以效仿?

近日&#xff0c;华为成功研发出自主可控的MetaERP系统&#xff0c;并完成了对旧有ERP系统的替换。该系统采用全栈自主可控技术&#xff0c;基于华为欧拉操作系统、GaussDB等根技术&#xff0c;采用云原生架构、元数据多租架构、实时智能技术等&#xff0c;提高业务效率&#x…...

自动驾驶——离散LQR的黎卡提方程Riccati公式推导与LQR工程化

1.LQR Question Background 之前写过连续系统的黎卡提方程Riccati推导&#xff0c;但是考虑到实际工程落地使用的是离散系统&#xff0c;于是又进行了离散黎卡提方程Riccati的公式推导。 2.Proof of Riccati Equation Formula for Discrete Systems 工程化落地&#xff0c;就…...

28.Mybatis的入门

目录 一、Mybatis的入门。 &#xff08;1&#xff09;Mybatis的简介。 &#xff08;2&#xff09;Mybatis的快速入门。 &#xff08;2.1&#xff09;快速入门。 &#xff08;2.2&#xff09;UserMapper.xml文件。 &#xff08;2.3&#xff09;sqlMapConfig.xml文件。 …...

Android Jetpack 从使用到源码深耕【ViewModel从实践到原理 】(三)

上文,我们通过简单的ViewModel使用源码入手,对其源码进行阅读,原理进行了简单总结,简单来说,ViewModel是通过Activity的onRetainNonConfigurationInstance 与 getLastNonConfigurationInstance的自动调用,实现了 ViewModel数据的存储和恢复,数据存储在ViewModelStore的m…...

什么性格的人适合报考环境科学类专业?高考选专业

环境科学类专业包括有&#xff1a;环境科学与工程&#xff0c;环境工程&#xff0c;环境科学&#xff0c;环境生态工程&#xff0c;环保设备工程&#xff0c;资源环境科学&#xff0c;水质科学与技术。 环境对于未来是一个极其重要的方向&#xff0c;需要学生具备一定的科学素…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

【Linux】shell脚本忽略错误继续执行

在 shell 脚本中&#xff0c;可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行&#xff0c;可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令&#xff0c;并忽略错误 rm somefile…...

智慧医疗能源事业线深度画像分析(上)

引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

vscode(仍待补充)

写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh&#xff1f; debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

视频字幕质量评估的大规模细粒度基准

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用&#xff0c;因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型&#xff08;VLMs&#xff09;在字幕生成方面…...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)

🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...