内存溢出和内存泄漏
内存溢出
内存溢出(OutOfMemoryError,简称OOM)是指没有空闲内存,且垃圾收集器也无法提供更多的内存
出现OOM的原因有两种:
- java虚拟机设置的堆内存不够
- 代码中创建了大量大对象,并且长时间不能被垃圾收集器收集
内存泄漏
可达性分析算法来判断对象是否是不再使用的对象,本质是判断一个对象是否还被引用,内存泄漏是指对象不会被程序用到了,但是GC又无法回收这些对象的情况,内存泄漏会逐渐的占用内存,直至耗尽所有内存,最终出现OOM
内存泄露的八种情况
静态集合类
1
2
3
4
5
6
7static List<Object> list = new ArrayList<>();
public void test(){
// 由于list是静态的,与JVM的生命周期相同,所以obj对象不会被回收
Object obj = new Object();
list.add(obj);
}单例模式
单例模式的对象实例是静态的,生命周期和JVM的生命周期相同,如果单例对象持有外部对象的引用,也会导致外部对象不会被回收
内部类持有外部类
内部类持有外部类对象,如果一个外部类的实例对象的方法返回了一个内部类的实例对象,这个内部类对象被长期引用了,即使那个外部类实例对象不再被使用,但由于内部类持有外部类的实例对象,这个外部类对象也不会被垃圾回收
各种连接(数据库连接、网络连接、io连接)
变量不合理的作用域
改变哈希值
缓存泄漏
可以使用WeakHashMap来使用缓存,当除了自身对key的引用外,此key没有其他引用,那么此map会自动丢弃此值
监听器和回调