Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java HashMap中的项是否在为null后被回收?_Java_Hashmap_Garbage Collection - Fatal编程技术网

Java HashMap中的项是否在为null后被回收?

Java HashMap中的项是否在为null后被回收?,java,hashmap,garbage-collection,Java,Hashmap,Garbage Collection,在下面的代码中,emp对象是否会被垃圾收集 import java.util.HashMap; public class Test { public static void main(String args[]) { HashMap<Employee, EmployeeVal> aMap = new HashMap<Employee, EmployeeVal>(); Empl

在下面的代码中,emp对象是否会被垃圾收集

import java.util.HashMap;   
public class Test {

    public static void main(String args[]) {
        HashMap<Employee, EmployeeVal> aMap = new 
                       HashMap<Employee, EmployeeVal>();

        Employee emp = new Employee("Vinoth");
        EmployeeVal val = new EmployeeVal("Programmer");

        aMap.put(emp, val);

        emp = null;

        System.gc();
        System.out.println("Size of Map" + aMap.size());

    }
}
import java.util.HashMap;
公开课考试{
公共静态void main(字符串参数[]){
HashMap aMap=new
HashMap();
员工emp=新员工(“维诺”);
EmployeeVal=新的EmployeeVal(“程序员”);
aMap.put(emp,val);
emp=null;
gc();
System.out.println(“地图大小”+aMap.Size());
}
}
看起来应该是这样,但不是根据这篇文章:


是否将
emp
设置为
null
,与此无关。应用逻辑保持不变;您正在将一个条目放入映射中,而从不删除它,因此
aMap.size()
的唯一有效答案是
1
(一个)

即使您永远无法访问映射的假设是正确的(事实并非如此,您可以通过
aMap.keySet().iterator().next()
,仅举一个例子,来检索
Employee
实例),例如,如果您创建了一个封装了另一个对象的类,而该对象从未分发过,它不允许更改基于封装的计算结果,比如
HashMap
报告的大小

关于这个问题的一个简单观点是,您持有对
HashMap
的引用,而HashMap又持有对
Employee
实例的引用

但实际上,这些对象可以被垃圾收集,只要JVM确保程序的正确性,例如,确保最后一个print语句生成Map1的输出
大小,这在技术上是可能的,而无需保留
HashMap
及其引用对象的整个内存。它只需保留
int size
字段的值,或者只需记住可预测的字符串结果

但是,虽然规范允许这样做,但不能保证。垃圾收集是一个尽力而为的过程。这些明显被引用的对象的收集只针对优化的代码,JVM通常不会优化由单个
main
方法组成的应用程序的代码,该方法在几毫秒内终止


底线是,无论JVM是否在幕后回收内存,垃圾收集都不会导致
HashMap
错误地更改其大小。

如果
HashMap
无缘无故地丢失其内容,那将是非常可怕的。现在还不清楚链接的帖子应该如何与你的问题联系起来。您的代码中既没有软引用也没有弱引用。这不是一个关于软引用和弱引用的问题。问题是,如果HashMap对一个为空的对象有一个强引用,那么分配给该对象的内存是否会被垃圾回收?我发布的代码的作者说不——“在上述情况下,对象不是垃圾收集的。”看起来应该是这样。您链接的帖子不包含您问题的代码,也没有对此做出任何声明。它只是描述了软引用和弱引用之间的区别。我修正了你的链接,指向包含代码和语句的帖子。“看起来应该是”。。。我不明白你为什么认为应该这样。JLS中是否有任何部分表明了这一点,或者有任何合理的理由说明为什么应该这样做?我想,“对象的置零”是造成您困惑的原因。只能“null”引用,不能为对象。在
对象a=新对象()中;对象b=a;a=零一个对象引用暂时存在两次,最后是一次。任何集合都有对其成员的引用。您通常看到的所有引用都是强引用,这些软引用、弱引用和虚引用很少使用(暂时忘记它们)。因此,只要集合成员仍然是成员,就不能对其进行GC(暂时忘记
WeakHashMap
),然后,不管您是否将变量设置为
null
,或者它没有检测到它;在这种情况下,它们仍然被地图引用这一事实很重要。所以在任何一种情况下,将变量设置为
null
都没有效果。@Holger我绝对记得这一点:什么时候我应该明确地将某个值设置为null?永远不要说从来没有我猜:)@Eugene:堆变量和问题的局部变量之间有区别。将局部变量设置为
null
很少有任何效果。相反,堆变量会产生影响,除了视频问题外,还必须覆盖未使用的引用变量,例如在
ArrayList.remove
中,仅更改大小是不够的,它必须用
null
覆盖最后一个数组项,否则,垃圾收集器没有机会理解它是“语义上不可访问的”。