Java内存泄漏
程序员文章站
2022-07-10 15:03:16
...
Java内存泄漏
- 什么是内存泄漏?
内存泄漏指的是存在“不再使用但持有引用”的对象,它们无法被GC回收,占用了内存的现象。轻微的内存泄漏不容易被察觉,严重的内存泄漏容易导致OOM(out of memory)。
- 哪些操作可能导致内存泄漏?
- 使用静态集合或数组而没有及时使用清除指向对象的引用导致;
- 使用 Set 集合保存对象,当修改对象属性后,无法通过该对象删除导致;
- 没有及时释放资源连接(IO连接,数据库连接,Socket网络连接等)导致,应在 finally 块中释放资源;
- 外部类持有内部类的引用没有及时清除;
- 模块之间方法调用,在参数中传递了对象引用,如果在被调用的模块方法中又将该引用赋值给了另一个引用,那么对于该传递的对象(堆上的对象)而言,需要同时清除多个引用才能被回收;
- 单例对象中如果持有其他对象的引用,那么该引用无法被清除;
- 使用 GUI API 编程时,使用到的各种监听器,是比较容易被忽略释放的;Java Web 编程中,监听器同样会被使用,但总体来说,数量有限。
Case 1
Static List<Object> list = new ArrayList<>(100); for (int i = 1; i < 100; i ++) { Object o = new Object(); list.add(o); o = null;// 只清除了创建时指向该对象的引用,而集合中仍然持有该对象引用 }
Case 2
// 以下这段代码基于 Person 对象重写了 hashCode() 方法 // 因为 HashSet 集合的删除是基于 Map 的,Set 集合中的对象在 Map 中 // 作为 key,而 Map(数组 + 链表)中 key 所在的数组的索引是根据 key // 的 hashCode() 计算的,当改变了 Set 中的对象,再用改变后的对象去 // 删除,自然是删除不掉的。 public static void main(String[] args) { Set<Person> set = new HashSet<Person>(); Person p1 = new Person("唐僧","pwd1",25); Person p2 = new Person("孙悟空","pwd2",26); Person p3 = new Person("猪八戒","pwd3",27); set.add(p1); set.add(p2); set.add(p3); System.out.println("总共有:"+set.size()+" 个元素!"); //结果:总共有:3 个元素! p3.setAge(2); //修改p3的年龄,此时p3元素对应的hashcode值发生改变 set.remove(p3); //此时remove不掉,造成内存泄漏 set.add(p3); //重新添加,居然添加成功 System.out.println("总共有:"+set.size()+" 个元素!"); //结果:总共有:4 个元素! }
其余略。
参考: http://blog.csdn.net/wtt945482445/article/details/52483944