被删空后收集的HashMap垃圾中的项目是什么?

时间:2022-09-07 23:58:06

In the following code, will the emp object be garbage collected?

在下面的代码中,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());

    }
}

It seems like it should be, but not according to this post:

它似乎应该是,但不是根据这篇文章:

What's the difference between SoftReference and WeakReference in Java?

Java中的SoftReference和WeakReference有什么区别?

1 个解决方案

#1


1  

Whether you set emp to null or not, is irrelevant. The application logic remains the same; you are putting an entry to the map, never remove it, thus the only valid answer to aMap.size() is 1 (one).

无论你是否将emp设置为null,都是无关紧要的。应用程序逻辑保持不变;你正在把一个条目放到地图上,永远不会删除它,因此aMap.size()的唯一有效答案是1(一)。

Even if your assumption, that you can never access the mapping, was right (it isn’t, you can retrieve the Employee instance via aMap.keySet().iterator().next(), to name just one example), e.g. if you create a class encapsulating another object that it never hands out, it didn’t allow to change the outcome of calculations based on the encapsulation, like the size reported by the HashMap.

即使你的假设,你永远不能访问映射,是正确的(它不是,你可以通过一个Map.keySet()。iterator()。next()来检索Employee实例,仅列举一个例子),例如,如果你创建一个封装另一个永远不会发出的对象的类,它就不允许根据封装更改计算结果,就像HashMap报告的大小一样。

A simple view on this issue, is, that you are holding a reference to HashMap, which in turn holds a reference to the Employee instance.

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

But actually, these objects can be garbage collected, as long as the JVM ensures the correctness of the program, e.g. ensures that the last print statement produces the output Size of Map1, which is technically possible without keeping the entire memory of the HashMap and its referenced objects. It would only have to keep the value of the int size field, or just remember the predictable string result.

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

But while this is allowed by the specification, it isn’t guaranteed. Garbage collection is a best-effort process. Collection of such apparently referenced objects only happens for optimized code and the JVM normally doesn’t optimize the code of an application consisting of a single main method that terminates within a few milliseconds.

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

The bottom line is, regardless of whether the JVM reclaims the memory behind the scenes, garbage collection will never cause a HashMap to spuriously change its size.

最重要的是,无论JVM是否回收幕后的内存,垃圾收集都不会导致HashMap虚假地改变其大小。

#1


1  

Whether you set emp to null or not, is irrelevant. The application logic remains the same; you are putting an entry to the map, never remove it, thus the only valid answer to aMap.size() is 1 (one).

无论你是否将emp设置为null,都是无关紧要的。应用程序逻辑保持不变;你正在把一个条目放到地图上,永远不会删除它,因此aMap.size()的唯一有效答案是1(一)。

Even if your assumption, that you can never access the mapping, was right (it isn’t, you can retrieve the Employee instance via aMap.keySet().iterator().next(), to name just one example), e.g. if you create a class encapsulating another object that it never hands out, it didn’t allow to change the outcome of calculations based on the encapsulation, like the size reported by the HashMap.

即使你的假设,你永远不能访问映射,是正确的(它不是,你可以通过一个Map.keySet()。iterator()。next()来检索Employee实例,仅列举一个例子),例如,如果你创建一个封装另一个永远不会发出的对象的类,它就不允许根据封装更改计算结果,就像HashMap报告的大小一样。

A simple view on this issue, is, that you are holding a reference to HashMap, which in turn holds a reference to the Employee instance.

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

But actually, these objects can be garbage collected, as long as the JVM ensures the correctness of the program, e.g. ensures that the last print statement produces the output Size of Map1, which is technically possible without keeping the entire memory of the HashMap and its referenced objects. It would only have to keep the value of the int size field, or just remember the predictable string result.

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

But while this is allowed by the specification, it isn’t guaranteed. Garbage collection is a best-effort process. Collection of such apparently referenced objects only happens for optimized code and the JVM normally doesn’t optimize the code of an application consisting of a single main method that terminates within a few milliseconds.

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

The bottom line is, regardless of whether the JVM reclaims the memory behind the scenes, garbage collection will never cause a HashMap to spuriously change its size.

最重要的是,无论JVM是否回收幕后的内存,垃圾收集都不会导致HashMap虚假地改变其大小。