在下面的代码中,是否会对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());
}
}
它似乎应该是,但不是根据这篇文章:
What's the difference between SoftReference and WeakReference in Java?
答案 0 :(得分:1)
无论您是否将emp
设置为null
,都无关紧要。应用程序逻辑保持不变;你正在为地图添加一个条目,永远不会删除它,因此aMap.size()
的唯一有效答案是1
(一)。
即使您假设您永远无法访问映射,但这是正确的(事实并非如此,您可以通过Employee
检索aMap.keySet().iterator().next()
个实例,仅举几个例子,例如,如果你创建一个封装另一个永远不会发出的对象的类,它就不允许根据封装更改计算结果,比如HashMap
报告的大小。
关于此问题的一个简单视图是,您持有对HashMap
的引用,Employee
依次保存对Size of Map1
实例的引用。
但实际上,这些对象可以进行垃圾收集,只要JVM确保程序的正确性,例如:确保最后一个print语句生成输出HashMap
,这在技术上是可行的,而不保留int size
及其引用对象的整个内存。它只需要保留main
字段的值,或者只记住可预测的字符串结果。
但是虽然规范允许这样做,但不能保证。垃圾收集是一个尽力而为的过程。这些明显引用的对象的集合仅发生在优化代码中,而JVM通常不会优化由单个HashMap
方法组成的应用程序的代码,该方法在几毫秒内终止。
最重要的是,无论JVM是否回收了幕后的内存,垃圾收集都不会导致display: block
虚假地改变其大小。