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、概述 大家好,我是欧阳方超。本次就Java中几个相似而又不同的概念做一下介绍。内存泄漏、内存溢出和栈溢出都是与内存相关的问题,但…...
时序预测 | Matlab实现SSA-GRU、GRU麻雀算法优化门控循环单元时间序列预测(含优化前后对比)
时序预测 | Matlab实现SSA-GRU、GRU麻雀算法优化门控循环单元时间序列预测(含优化前后对比) 目录 时序预测 | Matlab实现SSA-GRU、GRU麻雀算法优化门控循环单元时间序列预测(含优化前后对比)预测效果基本介绍程序设计参考资料 预测效果 基本介绍 Matlab实现SSA-GRU、GRU麻雀算法…...
Java+springboot开发的医院HIS信息管理系统实现,系统部署于云端,支持多租户SaaS模式
一、项目技术框架 前端:AngularNginx 后台:JavaSpring,SpringBoot,SpringMVC,SpringSecurity,MyBatisPlus,等 数据库:MySQL MyCat 缓存:RedisJ2Cache 消息队列&…...
【前端面经】Vue-Vue中的 $nextTick 有什么作用?
Vue.js 是一个流行的 JavaScript 框架,它提供了许多实用的功能,其中之一就是 $nextTick 方法。 在 Vue.js 中, $nextTick 方法可以确保我们在更新 DOM 之后再去执行某些操作,从而避免由于 DOM 更新而导致的问题。这个方法非常实用…...
基于STATCOM的风力发电机稳定性问题仿真分析(Simulink)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
如何写出高质量的代码
背景说明: 你是否曾经为自己写的代码而感到懊恼?你是否想过如何才能写出高质量代码?那就不要错过这个话题!在这里,我们可以讨论什么是高质量代码,如何写出高质量代码等问题。无论你是初学者还是资深开发人…...
15.基于主从博弈的智能小区代理商定价策略及电动汽车充电管理
说明书 MATLAB代码:基于主从博弈的智能小区代理商定价策略及电动汽车充电管理 关键词:电动汽车 主从博弈 动态定价 智能小区 充放电优化 参考文档:《基于主从博弈的智能小区代理商定价策略及电动汽车充电管理》基本复现 仿真平台&#…...
ChatGPT实现多语种翻译
语言翻译 多语种翻译是 NLP 领域的经典话题,也是过去很多 AI 研究的热门领域。一般来说,我们认为主流语种的互译一定程度上属于传统 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官方(下载jdk时找的) https://www.oracle.com/ 3.jdk8 https://www.oracle.com/java/technologies/downloads/ 下拉找到jdk8 切换windows (需要注册个oracle账…...
【10.HTML入门知识-CSS元素定位】
1 标准流(Normal Flow) 默认情况下,元素都是按照normal flow(标准流、常规流、正常流、文档流【document flow】)进行排布 从左到右、从上到下按顺序摆放好 默认情况下,互相之间不存在层叠现象 1.1…...
LeetCode_贪心算法_简单_455.分发饼干
目录 1.题目2.思路3.代码实现(Java) 1.题目 假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。 对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的…...
HashMap
目录 HashMap是什么? 为什么要使用HashMap? HashMap存储元素原理(put⽅法) 扰动函数 前置知识 异或运算 &运算 为什么使用扰动函数 实验验证扰动函数 常见问题 HashMap的默认长度是多少? HashMap是先扩…...
数据结构初阶 —— 树(堆)
目录 一,堆 堆的概念 向下调整法(数组) 向上调整法(数组) 堆的创建(建堆) 堆的实现 一,堆 堆的概念 如有个关键码的集合K{,,,...…...
一文看懂低代码,5分钟从入门到原理全搞定
全球低代码市场已经走过了近20年,中国低代码市场近5年经历了百花齐放的广泛探索阶段,更旺盛的市场需求逐步在被激发。现在,让我们按下暂停键,看看这些产品给我们呈现了低代码市场一幅怎样的百景图。 低代码平台简介 广义上的低代…...
MetaERP系统主要干什么的,华为自研ERP的路子是否可以效仿?
近日,华为成功研发出自主可控的MetaERP系统,并完成了对旧有ERP系统的替换。该系统采用全栈自主可控技术,基于华为欧拉操作系统、GaussDB等根技术,采用云原生架构、元数据多租架构、实时智能技术等,提高业务效率&#x…...
自动驾驶——离散LQR的黎卡提方程Riccati公式推导与LQR工程化
1.LQR Question Background 之前写过连续系统的黎卡提方程Riccati推导,但是考虑到实际工程落地使用的是离散系统,于是又进行了离散黎卡提方程Riccati的公式推导。 2.Proof of Riccati Equation Formula for Discrete Systems 工程化落地,就…...
28.Mybatis的入门
目录 一、Mybatis的入门。 (1)Mybatis的简介。 (2)Mybatis的快速入门。 (2.1)快速入门。 (2.2)UserMapper.xml文件。 (2.3)sqlMapConfig.xml文件。 …...
Android Jetpack 从使用到源码深耕【ViewModel从实践到原理 】(三)
上文,我们通过简单的ViewModel使用源码入手,对其源码进行阅读,原理进行了简单总结,简单来说,ViewModel是通过Activity的onRetainNonConfigurationInstance 与 getLastNonConfigurationInstance的自动调用,实现了 ViewModel数据的存储和恢复,数据存储在ViewModelStore的m…...
什么性格的人适合报考环境科学类专业?高考选专业
环境科学类专业包括有:环境科学与工程,环境工程,环境科学,环境生态工程,环保设备工程,资源环境科学,水质科学与技术。 环境对于未来是一个极其重要的方向,需要学生具备一定的科学素…...
XHS-Downloader终极指南:如何高效批量下载小红书内容
XHS-Downloader终极指南:如何高效批量下载小红书内容 【免费下载链接】XHS-Downloader 小红书(XiaoHongShu、RedNote)链接提取/作品采集工具:提取账号发布、收藏、点赞、专辑作品链接;提取搜索结果作品、用户链接&…...
如何用Fillinger脚本彻底告别Illustrator重复劳动:设计师的智能填充革命
如何用Fillinger脚本彻底告别Illustrator重复劳动:设计师的智能填充革命 【免费下载链接】illustrator-scripts Adobe Illustrator scripts 项目地址: https://gitcode.com/gh_mirrors/il/illustrator-scripts 你是不是也厌倦了在Illustrator中一遍遍复制粘贴…...
逆向工程ChatGPT:开源社区如何解构大语言模型黑盒
1. 项目概述:当开源精神“撞上”闭源巨兽最近在GitHub上闲逛,发现一个叫Zai-Kun/reverse-engineered-chatgpt的项目热度不低。光看名字就挺有意思的,“逆向工程ChatGPT”。这可不是什么破解软件或者绕过付费墙的小把戏,它背后代表…...
Arch Linux Hyprland自动化安装脚本:高效打造现代化Wayland桌面环境
Arch Linux Hyprland自动化安装脚本:高效打造现代化Wayland桌面环境 【免费下载链接】Arch-Hyprland For automated installation of Hyprland on Arch Linux or any Arch Linux-based distros 项目地址: https://gitcode.com/gh_mirrors/ar/Arch-Hyprland A…...
团队协作福音:如何用EasyYapi插件统一SpringBoot项目的接口文档风格?
团队协作福音:如何用EasyYapi插件统一SpringBoot项目的接口文档风格? 在微服务架构盛行的今天,一个SpringBoot项目往往由多个团队协作开发。当接口数量突破三位数时,文档风格不统一、字段说明缺失等问题会让协作效率直线下降。上周…...
WandEnhancer技术解密:如何通过本地化增强重新定义游戏修改体验
WandEnhancer技术解密:如何通过本地化增强重新定义游戏修改体验 【免费下载链接】Wand-Enhancer Advanced UX and interoperability extension for Wand (WeMod) app 项目地址: https://gitcode.com/gh_mirrors/we/Wand-Enhancer 你是否曾经面对游戏修改工具…...
一种用于并网光伏系统的创新型多层逆变器,以降低总谐波失真(THD)研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 🎁…...
3个高效方法:免费获取百度网盘高速下载直链的完整指南
3个高效方法:免费获取百度网盘高速下载直链的完整指南 【免费下载链接】baidu-wangpan-parse 获取百度网盘分享文件的下载地址 项目地址: https://gitcode.com/gh_mirrors/ba/baidu-wangpan-parse 当我们面对百度网盘缓慢的下载速度时,常常感到无…...
Steam Achievement Manager完整指南:快速解决游戏成就难题的终极工具
Steam Achievement Manager完整指南:快速解决游戏成就难题的终极工具 【免费下载链接】SteamAchievementManager A manager for game achievements in Steam. 项目地址: https://gitcode.com/gh_mirrors/st/SteamAchievementManager 核心关键词:S…...
从零构建本地化AI代码助手:架构、微调与工程实践
1. 项目概述:从零构建你自己的Claude代码助手最近在开发者社区里,一个名为“build-your-claude-code-from-scratch”的项目引起了我的注意。这个标题本身就充满了吸引力——它暗示着一种可能性:我们是否能够不依赖任何现成的、闭源的商业API&…...
