内存泄漏和内存溢出

概念

内存泄漏(memory leak):无法释放已经不再使用的内存空间。
内存溢出(out of memory): 程序申请的内存超过了现有的内存空间。

在JAVA虚拟机规范中,对JAVA虚拟机栈规定了两种异常状态:
如果线程请求的栈深度大于虚拟机所允许的深度,将抛出*Error;
如果虚拟机栈可以动态扩展,当扩展时无法申请到足够的内存时会抛出OutOfMemoryError;

内存泄漏

发生场景:

静态变量/静态引用/静态集合类:静态对象存放在方法区,随线程的结束而结束,会始终存在,如果对象比较复杂就会发生内存泄漏
各种连接未显示关闭:数据库连接、网络连接、IO连接,没显示的close,会造成很多对象无法回收
没有及时的将对象设置为空:例如集合的pop方法
监听器

避免内存泄漏:

尽早释放无用的引用
避免在循环语句中创建对象
尽量少用静态的变量

内存溢出

发生场景:

集合类中的对象的引用在使用完之后未清空,导致JVM不能回收。
内存中加载数据过大,如一次从数据库中读取大量的数据。
代码中的死循环或在循环体中产生多个重复对象实体。
启动JVM参数设置过小。
方法区主要存放的是类信息、常量、静态变量等。所以如果程序加载的类过多,或者使用反射、gclib等这种动态代理生成类的技术,就可能导致该区发生内存溢出

避免内存溢出(除了避免内存泄漏的几点之外还包括以下几点):

修改JVM启动参数,直接增加内存。
开启大型文件或从数据库一次拿了太多的数据很容易造成内存溢出,所以在这些地方要大概计算一下数据量的最大值是多少,并且设定所需最小及最大的内存空间值。

https://blog.csdn.net/u012813201/article/details/73793668
https://www.cnblogs.com/panxuejun/p/5883044.html