`
yinwufeng
  • 浏览: 287034 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Java集合HashSet的hashcode方法引起的内存泄漏问题

阅读更多
Java集合HashSet的hashcode方法引起的内存泄漏问题


注:试了试,arrayList也会有这种问题的。也是使用hashcode来比较的。




import java.util.HashSet;  
import java.util.Set;  
/** 
* Created on 2010-6-7 
* <p>Description: [HashSet的hashcode方法引起的内存泄漏]</p> 
* @author         shixing_11@sina.com 
* @version        1.0 
*/ 
public class HashSetTest  
{  
    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 个元素!  
        for (Person person : set)  
        {  
            System.out.println(person);  
        }  
          
    }  

package apistudy;
import java.util.HashSet;
import java.util.Set;
/**
* Created on 2010-6-7
* <p>Description: [HashSet的hashcode方法引起的内存泄漏]</p>
* @author         shixing_11@sina.com
* @version        1.0
*/
public class HashSetTest
{
    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 个元素!
        for (Person person : set)
        {
            System.out.println(person);
        }
       
    }
}
 

运行结果:

总共有:3 个元素!

总共有:4 个元素!

猪八戒-->pwd3-->2

孙悟空-->pwd2-->26

唐僧-->pwd1-->25

猪八戒-->pwd3-->2

总结:
HashSet中,在对应元素添加进set集合后,不要再去修改元素的值,否则对应元素的hashcode值发生变化,此时如果调用
集合的remove(),contains()方法,将不会得到正确的结果。remove()方法并不能正确remove掉对应的元素,造成内存泄漏。
Person.java

view plaincopy to clipboardprint?
package apistudy;  
public class Person  
{  
    private String username;  
    private String password;  
    private int age;  
    public Person(String username, String password, int age)  
    {  
        this.username = username;  
        this.password = password;  
        this.age = age;  
    }  
    public String getUsername()  
    {  
        return username;  
    }  
    public void setUsername(String username)  
    {  
        this.username = username;  
    }  
    public String getPassword()  
    {  
        return password;  
    }  
    public void setPassword(String password)  
    {  
        this.password = password;  
    }  
    public int getAge()  
    {  
        return age;  
    }  
    public void setAge(int age)  
    {  
        this.age = age;  
    }  
    @Override 
    public int hashCode()  
    {  
        final int prime = 31;  
        int result = 1;  
        result = prime * result + age;  
        result = prime * result + ((password == null) ? 0 : password.hashCode());  
        result = prime * result + ((username == null) ? 0 : username.hashCode());  
        return result;  
    }  
    @Override 
    public boolean equals(Object obj)  
    {  
        if (this == obj)  
            return true;  
        if (obj == null)  
            return false;  
        if (getClass() != obj.getClass())  
            return false;  
        Person other = (Person) obj;  
        if (age != other.age)  
            return false;  
        if (password == null)  
        {  
            if (other.password != null)  
                return false;  
        }  
        else if (!password.equals(other.password))  
            return false;  
        if (username == null)  
        {  
            if (other.username != null)  
                return false;  
        }  
        else if (!username.equals(other.username))  
            return false;  
        return true;  
    }  
    @Override 
    public String toString()  
    {  
        return this.username+"-->"+this.password+"-->"+this.age;  
    }  
      




本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/shixing_11/archive/2010/06/07/5652935.aspx
分享到:
评论

相关推荐

    hashCode内存溢出和内存泄漏的问题解决.docx

    内存管理和优化是编程中至关重要的环节,尤其是在Java这样的高级语言中,由于自动内存管理机制的存在,内存泄漏和溢出问题可能会变得难以察觉但后果严重。本文将深入探讨内存泄漏及其可能导致的内存溢出问题,以及...

    java内存泄露总结

    1. **静态集合类引起内存泄露** - **示例代码**: ```java static Vector v = new Vector(10); for (int i = 1; i ; i++) { Object o = new Object(); v.add(o); o = null; } ``` 在上述代码中,虽然局部...

    深入理解Java中的内存泄漏解决方案.docx

    4. **重构代码逻辑**:针对特定场景,比如`HashSet`中的对象属性更改导致的内存泄漏,可以通过重写`hashCode()`和`equals()`方法确保即使对象属性更改也能正确识别和删除。 5. **使用工具检测内存泄漏**:利用JVM...

    Java集合框架完整说明便于了解集合

    HashSet基于哈希表,无序且唯一,通过hashCode和equals方法保证元素唯一性。TreeSet内部实现为红黑树,元素自动排序,而LinkedHashSet则保持插入顺序。 3. Map接口:Map用于存储键值对,HashMap、HashTable、...

    java基础 集合-21-对象的一对多与多对多

    使用这种方式可以方便地在对象间导航,但需注意内存泄漏和循环引用的问题。 2. **对象的一对多关系**: 在Java中,一对多关系是最常见的关联,比如一个班级有多个学生。这通常通过在“多”端的类中定义集合类型的...

    黑马程序员-------hash改变造成的内存泄露

    在IT行业中,内存泄露是一个非常重要的问题,尤其是在Java这样的编程语言中。标题“黑马程序员------hash改变造成的内存泄露”提示我们,这个问题与哈希值的变化有关,这可能会导致程序无法正确地释放不再使用的内存...

    Java高新技术Java高新技术.doc

    8. **内存泄漏问题**:在`HashSet`中,对象的`hashCode`用于定位存储位置。如果对象的字段被修改,导致`hashCode`改变,那么在尝试删除对象时,由于新的`hashCode`找不到原有的位置,可能导致删除失败,从而引发内存...

    面试Java程序员最可能遇到的问题考试大全

    54. **Java集合框架结构**:包括接口如List, Set, Map,以及实现类如ArrayList, LinkedList, HashMap等,提供了丰富的数据结构和操作方法。 以上是对Java面试中可能出现的一些关键问题的详细解答,希望能帮助求职者...

    90个高质量的java问答.pdf

    Java 内存泄漏简介 - **内存泄漏原因**:探讨导致内存泄漏的常见原因,如循环引用和静态变量。 - **检测工具**:介绍用于检测内存泄漏的工具和技术。 - **预防措施**:提供防止内存泄漏的最佳实践建议。 #### 12. ...

    Java 一些值得注意的细节

    9. **集合框架的选择**:Java集合框架包括List、Set、Queue等接口,以及ArrayList、LinkedList、HashSet、HashMap等实现。根据需求选择合适的集合类型,如需保持顺序,使用ArrayList;需去重,使用HashSet。 10. **...

    java内容集合

    - **必要性**:避免内存泄漏和内存溢出等问题,提高程序运行效率。 #### 16. 短整型变量的运算问题 - **`short s1 = 1; s1 += 1;`**:使用复合赋值运算符时,Java 会自动进行类型转换,确保结果正确。 - **`short ...

    面试的27个经典问题(Java方面)

    10. **Java集合框架有哪些主要组件?** 集合框架包括List(如ArrayList和LinkedList)、Set(如HashSet和TreeSet)和Map(如HashMap和TreeMap)。它们提供了存储和操作对象的接口和实现。 11. **什么是Java反射API...

    java程序员面试宝典

    其次,深入理解Java集合框架是必备技能。集合框架包括List、Set、Map接口及其实现类,如ArrayList、LinkedList、HashSet、HashMap等。你需要熟悉它们的特性和应用场景,以及如何根据需求选择合适的数据结构。此外,...

    java后端面试题答案_pdf

    1. **List**: List是Java集合框架中的接口,它代表有序的元素序列,支持索引访问。ArrayList和LinkedList是两种常见的实现,前者在随机访问时性能更好,后者在插入和删除操作上更高效。 2. **Set**: Set接口不包含...

    Java 17道面试题和答案.docx

    Java集合框架包括List、Set和Map接口,以及它们的实现类如ArrayList、LinkedList、HashSet、HashMap等。这些集合提供了丰富的操作方法,方便存储和管理对象。 9. **泛型** 泛型是Java 5引入的特性,允许在类、...

    Java.Bug模式详解

    理解Java内存模型,合理设置堆大小,避免创建过大的对象,及时清理不再使用的对象,使用WeakReference和SoftReference管理对象,可以帮助防止内存溢出。 以上仅是部分常见的Java Bug模式,实际开发中还会有更多复杂...

    Java Bug 模式详解

    Java Bug模式详解是一种深入理解和解决Java编程中常见错误和陷阱的方法。这些模式通常源于语言特性、API使用不当或对编程规范的误解。本篇将详细探讨一些常见的Java Bug模式,并提供预防和修复策略。 1. **空指针...

    Java1.6源码

    6. **垃圾回收**:虽然JVM的垃圾回收机制在源码中并不直接可见,但通过研究`java.lang.ref`和`java.lang.instrument`等包,我们可以了解引用类型和内存监控的原理,这对于优化程序性能和避免内存泄漏至关重要。...

Global site tag (gtag.js) - Google Analytics