1.定义
内存溢出:通常发生在程序运行时,当程序所需内存超过了系统分配的内存空间,导致程序无法正常运行。包含OutOfMemoryError和StackOverflowError。
内存泄漏:程序在申请内存后未能正确释放,导致程序在持续运行过程中不断消耗系统资源,最终可能导致系统性能下降甚至崩溃。
2.产生原因
2.1 堆内存溢出:
- JVM内存太小
- 对象或者数组占用内存太大,包括生成的对象大或者从数据库取出的对象大;
2.2 栈内存溢出:
- 方法的递归调用,自己不停的调自己;
- 创建了太多的线程,线程也会占用内存;
- 死循环,while(true);
2.3 内存泄漏:
- 使用静态集合类,如使用静态的HashMap、LinkedList
- 对象没有及时释放,比如ThreadLocal;
- 大量的连接没有关闭,比如数据库连接,IO连接,网络连接;
- 变量不合理的作用域,一个变量仅仅在某个方法中使用,但是却定义成类变量
3.解决
分析工具:JVisualVM 、Arthas
内存溢出:
- 监控大对象、线程状态、连接数
- 优化JVM内存分配
- 优化代码,避免大对象,拆分大对象
- -Xss调大栈内存大小
内存泄漏:
- 及时关闭数据库连接,IO连接,网络连接连接
- 使用ThreadLocalMap的remove()回收ThreadLocal对象