HashMap如何避免内存泄露问题
HashMap对于Java开发人员来说,应该是一种非常非常熟悉的数据结构了,应用场景相当广泛。
本文重点不在于介绍如何使用HashMap,而是关注在使用HashMap过程中,可能会导致内存泄露的情况,下面将以示例的形式展开具体介绍。
为了更快的看到java.lang.OutOfMemoryError,我们可以配置下IDEA的JVM参数,简单配置下初始堆和最大堆参数为5M,-Xms5m -Xmx5m,如下图
不重写hashcode、equals
public class Test1 {public static void main(String[] args) {Map<People, Integer> map = new HashMap<People, Integer>(1000);int count = 0;while (true){People p = new People("zhangsan",10);map.put(p,1);count++;if (count % 1000 == 0){System.out.println("map size: " + map.size());System.out.println("运行"+count+"次后,可用内存剩余"+Runtime.getRuntime().freeMemory()/(1024*1024)+"MB");}}}
}
class People{private String name;private Integer age;public People(String name, Integer age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "People{" +"name='" + name + '\'' +", age=" + age +'}';}
}
结果分析:Object 的 hashcode 方法是本地方法,也就是用 c 或 c++ 实现的,该方法直接返回对象的内存地址,让后再转换整数,每次new的对象地址都不一样,就导致对象越来越多,最终触发OutOfMemoryError。
建议:当想要使用对象作为HashMap的key时,可以考虑使用不可变对象作为HashMap的key,比如常用的String类型,或者确保使用不可变的成员属性来生成hashcode;
- HashMap中数据在数组中的存放位置,是取决于Key对象的 hashCode() 方法的。
- 一个对象的hashCode() 方法的值,一般来说都是和对象的内容相关的。那么,如果Key对象的成员取值变化了,它的hashCode() 基本上也会变化。
- 在存放进去的时候,和取出数值的时候,都是依赖Key 对象的hashCode计算的。
为什么重写equals还要重写hashcode方法
可以参考这篇文章
https://donglin.blog.csdn.net/article/details/129018073