黑马程序员技术交流社区
标题:
关于HashSet内存泄漏的问题
[打印本页]
作者:
未知数|X|
时间:
2013-10-28 07:22
标题:
关于HashSet内存泄漏的问题
本帖最后由 未知数|X| 于 2013-10-29 14:21 编辑
为什么是说HashSet存在内存泄漏?,它的内存泄漏是怎样造成的?
作者:
孙涛00
时间:
2013-10-28 07:59
HashSet就是采用哈希算法存储对象的,他内部采用了对某个数字进行取模的方式对所有的哈希码进行分组划分的对象存储区域
Object中定义了一个hashCode方法用来返回每个java对象的哈希码,当从hashSet集合中查找某个对象时,java系统首先调用对象的hashCode()方法获得该对象的哈希码,然后根据哈希码值找到相应的存储区域,最后取出该存储区域没的每个元素与该元素进行equals方法比较,这样不用遍历整个HashSet集合,就能得到结论。
public class ReflectPoint {
String str1 = "sontao";//此处没有public
public String str2 = "foxiaotao";
public String str3 = "ou mygod";
private int x;
public int y;
public ReflectPoint(int x, int y) {
this.x = x;
this.y = y;
}
public ReflectPoint(){}
public String toString()
{
return str1+" : "+str2+" : "+str3;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ReflectPoint other = (ReflectPoint) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
}
复制代码
public static void main(String[] args) {
// TODO Auto-generated method stub
Collection collections=null;
try
{
// InputStream ips = new FileInputStream("config.properties");
// InputStream ips = ArrayList_HashSet.class.getClassLoader().getResourceAsStream("cn/itcast/day1/config.properties");
InputStream ips = ArrayList_HashSet.class.getResourceAsStream("resources/config.properties");
Properties prop = new Properties();
prop.load(ips);
ips.close();
String className = prop.getProperty("className");
collections = (Collection)Class.forName(className).newInstance();
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ReflectPoint pt1 = new ReflectPoint(3,3);
ReflectPoint pt2 = new ReflectPoint(4,4);
ReflectPoint pt3 = new ReflectPoint(3,3);
collections.add(pt1);
collections.add(pt2);
collections.add(pt3);//复写了ReflectPoint的hashCode方法和equals方法
collections.add(pt1);
pt1.y=7;
collections.remove(pt1);//内存泄露,没能移除
System.out.println(collections.size());
}
}
复制代码
结果:2
在例子中复写hashCode()和equals()方法,根据ReflectPoint的x,y的值确定对象的hashCode()值,这样pt1和pt3就是同一个对象,如果不复写hashCode(),pt1和pt3就不是同一个对象。
将pt1,pt2,pt3添加进集合中去之后,改变pt1.y的值
pt1.y=7;
这是从集合中移除pt1。
但是pt1在原来的HashSet中的存储位置已经由y值得改变而改变。程序这是不发现pt1新的位置。所以移除不出去,这样程序员以为移除了,但是pt1还在内存中,造成内存泄露。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2