Java内存泄漏_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > Java内存泄漏

Java内存泄漏

 2018/3/9 18:39:39  getthrough  程序员俱乐部  我要评论(0)
  • 摘要:Java内存泄漏什么是内存泄漏?内存泄漏指的是存在“不再使用但持有引用”的对象,它们无法被GC回收,占用了内存的现象。轻微的内存泄漏不容易被察觉,严重的内存泄漏容易导致OOM(outofmemory)。哪些操作可能导致内存泄漏?使用静态集合或数组而没有及时使用清除指向对象的引用导致;使用Set集合保存对象,当修改对象属性后,无法通过该对象删除导致;没有及时释放资源连接(IO连接,数据库连接,Socket网络连接等)导致,应在finally块中释放资源;外部类持有内部类的引用没有及时清除
  • 标签:Java 内存

Java内存泄漏

  • 什么是内存泄漏?

? ? ? ? 内存泄漏指的是存在“不再使用但持有引用”的对象,它们无法被GC回收,占用了内存的现象。轻微的内存泄漏不容易被察觉,严重的内存泄漏容易导致OOM(out of memory)。

?

  • 哪些操作可能导致内存泄漏?
  1. 使用静态集合或数组而没有及时使用清除指向对象的引用导致;
  2. 使用 Set 集合保存对象,当修改对象属性后,无法通过该对象删除导致;
  3. 没有及时释放资源连接(IO连接,数据库连接,Socket网络连接等)导致,应在 finally 块中释放资源;
  4. 外部类持有内部类的引用没有及时清除;
  5. 模块之间方法调用,在参数中传递了对象引用,如果在被调用的模块方法中又将该引用赋值给了另一个引用,那么对于该传递的对象(堆上的对象)而言,需要同时清除多个引用才能被回收;
  6. 单例对象中如果持有其他对象的引用,那么该引用无法被清除;
  7. 使用 GUI API 编程时,使用到的各种监听器,是比较容易被忽略释放的;Java Web 编程中,监听器同样会被使用,但总体来说,数量有限。

Case 1

class="java" name="code">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

?

?

?

发表评论
用户名: 匿名