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值不同,查找不到对应的对象,因此无法删除,但是对应的引用还保存所以无法回收

时间: 2024-10-03 13:09:46

HashSet内存泄露的相关文章

Java 内存泄露(二)

一.Java内存回收机制 不论哪种语言的内存分配方式,都需要返回所分配内存的真实地址,也就是返回一个指针到内存块的首地址.Java中对象是采用new或者反射的方法创建的(还有克隆),这些对象的创建都是在堆(Heap)中分配的,所有对象的回收都是由Java虚拟机通过垃圾回收机制完成的.GC为了能够正确释放对象,会监控每个对象的运行状况,对他们的申请.引用.被引用.赋值等状况进行监控,Java会使用有向图的方法进行管理内存,实时监控对象是否可以达到,如果不可到达,则就将其回收,这样也可以消除引用循环

深入Android内存泄露

深入内存泄露 Android应用的内存泄露,其实就是java虚拟机的堆内存泄漏. 1.知识储备 1.Java内存模型 相关内存对象模型,参照博客精讲Java内存模型 1) 寄存器(register).这是最快的保存区域,这是主要由于它位于处理器内部.然而,寄存器的数量十分有限,所以寄存器是需要由编译器分配的.我们对此没有直接的控制权,也不可能在自己的程序里找到寄存器存在的任何踪迹. (2) 堆栈(stack).在执行函数(方法)时,函数一些内部变量的存储都可以放在栈上面创建,函数执行结束的时候这

Java中会有内存泄露吗?

一.Java内存回收机制 不论哪种语言的内存分配方式,都需要返回所分配内存的真实地址,也就是返回一个指针到内存块的首地址.Java中对象是采用new或者反射的方法创建的, 这些对象的创建都是在堆(Heap)中分配的,所有对象的回收都是由Java虚拟机通过垃圾回收机制完成的.GC为了能够正确释放对象,会监控每个对象的 运行状况,对他们的申请.引用.被引用.赋值等状况进行监控,Java会使用有向图的方法进行管理内存,实时监控对象是否可以达到,如果不可到达,则就将 其回收,这样也可以消除引用循环的问题

Java SE 基础复习-内存泄露

一.Java内存回收机制 不论哪种语言的内存分配方式,都需要返回所分配内存的真实地址,也就是返回一个指针到内存块的首地址.Java中对象是采用new或者反射的方法创建的,这些对象的创建都是在堆(Heap)中分配的,所有对象的回收都是由Java虚拟机通过垃圾回收机制完成的.GC为了能够正确释放对象,会监控每个对象的运行状况,对他们的申请.引用.被引用.赋值等状况进行监控,Java会使用有向图的方法进行管理内存,实时监控对象是否可以达到,如果不可到达,则就将其回收,这样也可以消除引用循环的问题.在J

JAVA中会存在内存泄露吗

所谓内存泄露就是指一个不再被程序使用的对象或变量一直被占据在内存中.java中有垃圾回收机制,它可以保证一对象不再被引用的时候,即对象编程了孤儿的时候,对象将自动被垃圾回收器从内存中清除掉.由于Java 使用有向图的方式进行垃圾回收管理,可以消除引用循环的问题,例如有两个对象,相互引用,只要它们和根进程不可达的,那么GC也是可以回收它们的,例如下面的代码可以看到这种情况的内存回收: package com.huawei.interview; import java.io.IOException;

黑马程序员——hashCode方法的作用,java内存泄露

hashCode方法的作用:当有一个对象要存入hash集合的时候,JVM首先会调用hashCode方法获取该对象的哈希值,然后根据哈希值找到相应的存储区域,最后取出该区域的所有元素与该对象进行equals比较,如果相等,不存入该元素,否则,存入.这样不用遍历集合中的所有元素就能的到我们想要的结果,提高了查找的效率.但是如果不覆写hashCode方法的话,相同的对象可能会存储在HashSet集合中,虽然他们equals比较相同,但他们的内存区域不同的话,就不会进行equals比较了.为了让两个相同

如何用Java编写一段代码引发内存泄露

Q:刚才我参加了面试,面试官问我如何写出会发生内存泄露的Java代码.这个问题我一点思路都没有,好囧. A1:通过以下步骤可以很容易产生内存泄露(程序代码不能访问到某些对象,但是它们仍然保存在内存中): 应用程序创建一个长时间运行的线程(或者使用线程池,会更快地发生内存泄露). 线程通过某个类加载器(可以自定义)加载一个类. 该类分配了大块内存(比如new byte[1000000]),在某个静态变量存储一个强引用,然后在ThreadLocal中存储它自身的引用.分配额外的内存new byte[

JAVA内存溢出与内存泄露

虽然jvm可以通过GC自动回收无用的内存,但是代码不好的话仍然存在内存溢出的风险. 最近在网上搜集了一些资料,现整理如下: —————————————————————————————————————————— 一.为什么要了解内存泄露和内存溢出? 1.内存泄露一般是代码设计存在缺陷导致的,通过了解内存泄露的场景,可以避免不必要的内存溢出和提高自己的代码编写水平: 2.通过了解内存溢出的几种常见情况,可以在出现内存溢出的时候快速的定位问题的位置,缩短解决故障的时间. 二.基本概念 理解这两个概念非

理解内存泄露的本质

1.内存泄露的本质是什么呢 就是长生命周期的对象引用短生命周期的对象,长生命周期总是持有段生命周期的引用造成了对短生命周期对象的不能回收 2.静态集合类引起内存泄露 因为静态对象跟应用程序的生命周期一样 Static Vector v = new Vector(10); for (int i = 1; i<100; i++) { Object o = new Object(); v.add(o); o = null; }// 在这个例子中,循环申请Object 对象,并将所申请的对象放入一个Ve