内存溢出与内存泄露知识点总结
Posted wodongx123
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了内存溢出与内存泄露知识点总结相关的知识,希望对你有一定的参考价值。
内存溢出与内存泄露
1. 内存溢出
程序在申请内存时,没有足够的内存可以申请,于是程序报错OOM(Out of Memory)。
JVM的内存空间,用的比较多的部分就是堆内存和栈内存,所以内存溢出也分为堆内存溢出和栈内存溢出的情况。
1.1 无限申请对象引起的堆内存溢出
ArrayList list = new ArrayList();
while(true)
list.add(new Object());
由于在堆中申请的new ArrayList的被list所持有,所以当内存堆满之后,new ArrayList不会被回收
而内部申请的无数个Object被new ArrayList所持有,所以也不会被回收。由于无法回收内存,而同时正在申请新的内存,所以就报了OOM。
1.2 无限调用方法引起的栈内存溢出
public static void main(String[] args)
new Test().fun();
public void fun()
fun();
在JVM中,每调用一次方法,都会在java栈中生成一个新的栈帧,这些栈帧带有局部变量表,操作数栈,动态连接,方法返回地址等数据内容,会占用内存空间。而当我们无限的调用方法后,由于无法清栈,最终会导致栈内存溢出。
栈内存溢出JVM会报StackOverFlow的错误。
Exception in thread "main" java.lang.StackOverflowError
at Test.fun(Test.java:13)
at Test.fun(Test.java:13)
at Test.fun(Test.java:13)
......无数个同名方法......
at Test.fun(Test.java:13)
报错的基本情况
- 同一个方法的反复调用,比如DFS的层数过多导致爆栈。
- 方法调用形成一个闭环,A调用B,B调用C,C调用D,D又调用A。于是方法一直被调用导致爆栈。
- 方法调用没有形成闭环,但是就是调用了太多的方法,导致爆栈。(不太可能)
2. 内存泄露
指程序在申请内存后,被某个对象一直持有,无法释放已经申请的内存空间。
当程序出现了多次内存泄露后,被无用内存占用的内存空间就会变多,可用的内存就会变少。
就更容易报OOM。
内存泄露的本质是:一个生命周期较长的对象,持有了一个生命周期较短的对象。导致生命周期短的对象在完成了他的任务之后,无法被系统所回收,导致的无用内存变多。
https://blog.csdn.net/qq_41872247/article/details/102996721
3. 内存抖动
是指在短时间内,有大量的对象被创建或者回收的情况。造成的原因是频繁在循环中创建对象。
由于创建对象非常频繁,且新对象需要内存。一旦内存空间不足,就会触发GC,回收掉不需要使用的内存。
内存抖动就是指频繁创建对象而导致的频繁触发GC的情况。
GC一旦被频繁触发,就会导致应用程序卡顿。
fastjson使用时,将json转成javabean时就会触发内存抖动。
如何避免:
不要在会频繁调用的方法中,创建对象,而改用成员变量的方式。比如说view的onDraw方法,onTouchEvent方法等。
以上是关于内存溢出与内存泄露知识点总结的主要内容,如果未能解决你的问题,请参考以下文章