HashSet内存泄露

 1 import java.util.HashSet;
 2 import java.util.Set;
 3 
 4 public class PersonTest {
 5 
 6     public static void main(String[] args) {
 7         Set<Person> ps = new HashSet<>();
 8         Person p = new Person("joshua", 25);
 9 
10         ps.add(p);
11         p.name = "aw";
12         ps.remove(p);
13         System.out.println(ps.size());
14     }
15 }
16 
17 class Person {
18     String name;
19     int age;
20 
21     public Person(String name, int age) {
22         super();
23         this.name = name;
24         this.age = age;
25     }
26 
27     @Override
28     public int hashCode() {
29         final int prime = 31;
30         int result = 1;
31         result = prime * result + age;
32         result = prime * result + ((name == null) ? 0 : name.hashCode());
33         return result;
34     }
35 
36     @Override
37     public boolean equals(Object obj) {
38         if (this == obj)
39             return true;
40         if (obj == null)
41             return false;
42         if (getClass() != obj.getClass())
43             return false;
44         Person other = (Person) obj;
45         if (age != other.age)
46             return false;
47         if (name == null) {
48             if (other.name != null)
49                 return false;
50         } else if (!name.equals(other.name))
51             return false;
52         return true;
53     }
54 }

程序输出结果为:1

分析:

0. Person的hash值由name和age共同计算得出

1. 当p插入ps中时,根据name与age计算hash值进行插入

2. 插入后改变了对象p的name值

3. remove(p)时根据新的name与age计算hash值进行查找(此hash值不同于原hash值)

4. 由于hash值不同,查找不到对应的对象,因此无法删除,但是对应的引用还保存所以无法回收

结论:

1. 对象加入Hash表中之后不要更改用于计算Hash值的属性

2. 会发生改变的属性不要用于计算Hash值

原文地址:https://www.cnblogs.com/joshua-aw/p/6011732.html