内存溢出和内存泄露的区别

这道题是面试常考的,一定要区分好区别,我之前就是直接认为内存溢出就是内存泄漏了

概念

内存溢出:是指程序在申请内存时,没有足够的内存空间供其使用。比如,申请了一个整数的内存,但实际存了一个需要 long 类型来存储的数,这就会导致内存溢出。系统无法满足程序需要的内存大小,导致溢出。

内存泄漏:是指程序在申请内存后,无法释放已申请的内存空间。虽然单个内存泄漏可能不会带来太大问题,但随着内存泄漏的积累,系统的可用内存空间会逐渐减少。就像一个容器只能装4个水果,但你却放了5个,结果溢出并掉落在地上。内存泄漏最终可能会导致内存耗尽,也就是内存溢出。

内存溢出分类

  1. PermGen Space

    • PermGen(Permanent Generation)是指JVM内存的永久保存区域,存放类和Meta信息。这个区域不同于存放实例的Heap区域,且在运行期间GC不会对其进行清理。如果应用中有大量的Class信息,就可能出现PermGen Space错误。
    • 比如,在Web服务器中对JSP进行precompile时,或者应用中使用了大量第三方jar文件超出默认大小(4M)都可能导致此错误。
  2. Java Heap Space

    • Java Heap是用于存储实例对象的内存区域。默认情况下,其大小为物理内存的1/64,最大空间为物理内存的1/4。如果内存剩余不到40%,JVM会增大堆到最大设置值,超过70%,则会减小堆到最小设置值。
    • 通常,Xmx和Xms设置相同避免频繁调整虚拟机堆的大小。如果Xms超过了Xmx值,或者堆和非堆的总和超过了物理内存限制都会导致启动问题。

内存泄漏分类

  1. 常发性内存泄漏:代码重复执行导致内存泄漏。
  2. 偶发性内存泄漏:在特定环境或操作过程下才会发生的内存泄漏。
  3. 一次性内存泄漏:发生一次或由于算法上的缺陷导致总会有一块内存泄漏。
  4. 隐式内存泄漏:程序运行过程中不断分配内存,但最终才释放,可能最终耗尽系统所有内存。

发生场景以及解决方法

内存溢出

内存溢出通常由以下原因引起:

  1. 过多数据加载:从数据库等源加载大量数据到内存可能引发溢出。
  2. 未清空集合中的对象引用:集合中对象引用未被清空,导致JVM无法回收。
  3. 死循环或对象重复创建:存在代码中的无限循环或重复创建大量对象。
  4. 第三方软件中的问题:使用的第三方软件存在bug导致内存溢出。
  5. 启动参数内存值设定过小:设置的启动参数不足以支持应用所需内存。

解决内存溢出的方法:

  1. 调整JVM启动参数:增加内存限制(使用 -Xms 和 -Xmx 参数)。
  2. 检查错误日志:查看 "OutOfMemory" 错误前是否有其他异常或错误。
  3. 代码审查和分析:检查可能导致内存溢出的代码部分。

具体排查重点:

  1. 数据查询优化:避免一次性加载过多数据库数据,尤其使用分页查询方式。
  2. 死循环和递归调用:审查代码中是否存在无限循环或过度递归。
  3. 对象重复创建:检查代码,确保大循环未创建大量重复对象。
  4. 集合对象引用清除:确认集合对象在使用完后进行清除,避免持有无用对象的引用。
  5. 动态内存查看工具:使用内存查看工具实时监控和分析内存使用情况。

内存泄漏

具体排查重点:

检测工具

  • Valgrind和Dmalloc:这些工具能够跟踪内存的分配和释放,输出内存使用情况以及追踪错误,帮助发现潜在的内存泄漏。

日志记录

  • 记录内存申请和释放:在代码中添加日志记录,包括内存的申请、释放以及使用情况。观察日志可以发现潜在的内存泄漏。

性能分析器

  • gprof和perf:这些性能分析工具可以识别性能瓶颈和内存使用情况,用于检测内存泄漏问题。

解决方法

  • 智能指针的使用:采用智能指针(如std::shared_ptr或std::unique_ptr)来管理内存,自动释放内存并避免泄漏。
  • 手动释放内存:在代码中手动添加释放内存的语句,确保每次申请的内存都得到释放。
  • 定期清理缓存:缓存、连接池等容易导致泄漏,定期清理这些资源可以有效避免内存泄漏。
  • 增加内存判断:在程序中增加内存判断的代码,例如使用assert等断言库,确保内存的正确使用。
相关推荐
码事漫谈11 小时前
黄仁勋被裁第一天,就收到了橄榄枝
后端
金銀銅鐵12 小时前
带您看懂字节码指令(二):空循环里有什么
java·后端·ai编程
皮皮林55113 小时前
比 Xshell 还好用的 SSH 客户端神器,MobaXterm 太爱了!
后端
我不会起名字32214 小时前
会话缓存失效排查:区分 Redis 失效与节点广播
redis·后端·go·即时通讯·im·故障排查
深入云栈16 小时前
Netty 4.2.x 源码深度解析 (二十三):ByteBuf 核心设计 —— 索引、类型与零拷贝
java·后端·架构
JackJiang16 小时前
IM踩坑:聊天消息ID怎么设计?一个UUID搞不定,我用双ID解决
后端·架构
开心猴爷16 小时前
iOS 上架 App 流程
后端·ios
code_Bo16 小时前
不只命令行:我把跨 Agent 会话同步做成了桌面应用
前端·javascript·后端
用户83562907805117 小时前
使用 Python 控制 Excel 工作表的分页位置
后端·python
用户83562907805117 小时前
Python 如何在 Word 中添加和管理文档变量
后端·python