A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 未知数|X| 中级黑马   /  2013-10-28 07:22  /  957 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 未知数|X| 于 2013-10-29 14:21 编辑

为什么是说HashSet存在内存泄漏?,它的内存泄漏是怎样造成的?

1 个回复

倒序浏览
HashSet就是采用哈希算法存储对象的,他内部采用了对某个数字进行取模的方式对所有的哈希码进行分组划分的对象存储区域

Object中定义了一个hashCode方法用来返回每个java对象的哈希码,当从hashSet集合中查找某个对象时,java系统首先调用对象的hashCode()方法获得该对象的哈希码,然后根据哈希码值找到相应的存储区域,最后取出该存储区域没的每个元素与该元素进行equals方法比较,这样不用遍历整个HashSet集合,就能得到结论。
  1. public class ReflectPoint {

  2.         String str1 = "sontao";//此处没有public
  3.         public String str2 = "foxiaotao";
  4.         public String str3 = "ou mygod";
  5.         private int x;
  6.         public int y;
  7.         public ReflectPoint(int x, int y) {
  8.                 this.x = x;
  9.                 this.y = y;
  10.         }
  11.         public ReflectPoint(){}
  12.         public String toString()
  13.         {
  14.                 return str1+" : "+str2+" : "+str3;
  15.         }
  16.        
  17.         @Override
  18.         public int hashCode() {
  19.                 final int prime = 31;
  20.                 int result = 1;
  21.                 result = prime * result + x;
  22.                 result = prime * result + y;
  23.                 return result;
  24.         }
  25.         @Override
  26.         public boolean equals(Object obj) {
  27.                 if (this == obj)
  28.                         return true;
  29.                 if (obj == null)
  30.                         return false;
  31.                 if (getClass() != obj.getClass())
  32.                         return false;
  33.                 ReflectPoint other = (ReflectPoint) obj;
  34.                 if (x != other.x)
  35.                         return false;
  36.                 if (y != other.y)
  37.                         return false;
  38.                 return true;
  39.         }
  40. }
复制代码
  1.         public static void main(String[] args) {
  2.                 // TODO Auto-generated method stub
  3.                 Collection collections=null;
  4.                 try
  5.                 {
  6. //                        InputStream ips = new FileInputStream("config.properties");
  7. //                        InputStream ips = ArrayList_HashSet.class.getClassLoader().getResourceAsStream("cn/itcast/day1/config.properties");
  8.                         InputStream ips = ArrayList_HashSet.class.getResourceAsStream("resources/config.properties");
  9.                         Properties prop = new Properties();
  10.                         prop.load(ips);
  11.                         ips.close();
  12.                         String className = prop.getProperty("className");
  13.                         collections = (Collection)Class.forName(className).newInstance();
  14.                 }
  15.                 catch (Exception e) {
  16.                         // TODO Auto-generated catch block
  17.                         e.printStackTrace();
  18.                 }
  19.                 ReflectPoint pt1 = new ReflectPoint(3,3);
  20.                 ReflectPoint pt2 = new ReflectPoint(4,4);
  21.                 ReflectPoint pt3 = new ReflectPoint(3,3);
  22.                 collections.add(pt1);
  23.                 collections.add(pt2);
  24.                 collections.add(pt3);//复写了ReflectPoint的hashCode方法和equals方法
  25.                 collections.add(pt1);
  26.                 pt1.y=7;
  27.                 collections.remove(pt1);//内存泄露,没能移除
  28.                 System.out.println(collections.size());
  29.         }

  30. }
复制代码
结果: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还在内存中,造成内存泄露。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马