内存泄漏和内存溢出


相关文章:
JVM内存模型
Java GC垃圾回收机制

一、内存泄漏

Memory Leak,内存泄漏,在 JAVA 语言中指的是申请的内存空间不能被正常回收,导致后续程序里这块内存被永远占用(不可达),当指向这块内存空间的指针不再存在时,这块内存也就永远不可达了,这块内存空间就被泄漏了。

一般情况下,少量的内存泄漏不会有什么影响,但是长期大量的内存泄漏可能会引起内存溢出。

借用别人的比喻就是:

比如有 10 张纸,本来一人一张,画完自己擦了还回去,别人可以继续画。
现在有个坏蛋要了纸不还,然后还跑了找不到人了,如此就只剩下 9 张纸给别人用了。

这种情况就相当于 "内存泄漏" 了。
这种不道德的人多了,最后纸都 "泄漏" 完了,再有人来要纸就没有了,就变成 "内存溢出" 了。

在 C/C++ 中,程序员动态申请的内存空间通常需要人为调用 free/delete 来释放,否则内存会一直被占用,不会自动释放,于是就很容易造成内存泄漏。

而在 Java 中,JVM GC 垃圾回收机制会自动回收不可达对象,不需要程序员手动释放空间,大大减少了内存泄漏的可能性。

二、内存溢出

内存溢出,其实就是内存越界,是指存储的数据超出了可分配的空间大小,这时程序就会出现内存溢出错误。

内存溢出通常是内存不足,内存泄漏通常是指内存空间没有正常回收或无法回收。

在 JAVA 语言中,内存溢出包括两类情况:

  • StackOverFlowError:通常是栈深度不足导致的栈内存溢出
  • OutOfMemoryError:通常是内存空间不足导致的内存溢出

1、StackOverFlow

StackOverFlow,通常称为栈溢出。

先看一下之前的文章中讲过的 JVM 的内存模型,如下图所示:

JVM 内存模型

在 Java 中,栈是由许多栈帧(Stack frame)组成,一个栈帧包含一个 Java 方法的调用状态。

执行每个方法时都会在调用栈上分配一个栈帧 (Stack Frame),用于存储引用方法的参数、方法中定义的变量、操作数栈、方法的返回地址等信息。

栈帧随着方法调用而创建,随着方法结束而销毁。

如果在调用方法时,线程请求的栈深度大于 JVM 允许的深度,就会抛出 StackOverflowError 栈溢出错误。(最常见的可能耗光 Java 栈深度的场景是方法递归)

2、OutOfMemory

OutOfMemoryError,简称 OOM。

很多时候会认为内存溢出就是指 OOM,其实二者并不等价,只能说因为 OOM 引起内存溢出的情况比较多一些。

在 Java 中,
出现 OOM 最多的就是堆内存溢出,一般是类似下面这样的报错:

java.lang.OutOfMemoryError: Java heap space

当出现类似这样的报错信息后,就要进一步排查错误日志、参数配置、代码等方面。

更多 OOM 问题的分析和解决在后面详细讲解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值