如何释放 HashSet 中一个元素的内存?

How to free the memory of one element in a HashSet?

提问人:Rook 提问时间:9/28/2023 最后编辑:Mark RotteveelRook 更新时间:9/29/2023 访问量:57

问:

如果我有这样的代码:

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();   //an integer
        int q = scanner.nextInt();   //an integer less than or equal to n
 
        Set<String> map = new HashSet<>();
        for (int i = 0; i < n; i++) {
            String input = scanner.next();
            map.add(input);
        }
 
        for (int i = 0; i < q; i++) {
            String input= scanner.next();
            if (whitelist.contains(input)) {
                //code I want to improve on
                map.remove(input);
                System.out.println("accept");
            } else {
                System.out.println("reject");
            }
        }
    }
}

在第二个 for 循环中从哈希集中删除元素后,那里保存的内存会被释放吗?如果没有,我该怎么做才能真正释放它以获得更多可以分配的内存?

另外,是否可以在使用后立即从扫描仪中释放输入?就像在打印出“accept”或“reject”后从第二个for循环中释放输入,这样它就不会占用内存?

我已经搜索了释放内存的方法,但我唯一找到的是使用 .clear() 函数删除地图中的所有条目,这是我不想要的。

内存管理 java.util.scanner 哈希集

评论

8赞 Sweeper 9/28/2023
您不能在 Java 中直接释放托管内存。您可以使其符合垃圾回收条件,垃圾回收器将在某个时候释放它。
5赞 Stephen C 9/28/2023
JVM 知道何时释放内存......它不需要你的帮助来实现它。事实上,如果你试图帮助它,你很可能会让事情变得更糟,无论是小的还是大的。

答:

1赞 Basil Bourque 9/28/2023 #1

TL的;博士

我该怎么做才能真正释放它以获得更多可以分配的内存

无。您不执行任何专门释放内存的操作。

在 Java 中,您不直接管理内存。Java 中没有 malloc 供您反转,也没有任何引用计数供您跟踪。

当一个对象不再有指向它的引用时,它将成为最终垃圾回收的候选对象。稍后将根据 JVM 的特定垃圾回收器实现的规则释放内存。

在特定代码中,每个对象只有三个引用:String

  • input第一个循环中的引用变量。for
  • input第二个循环中的引用变量。for
  • 作为 .Set

前两个(参考变量)在退出各自循环的每个循环时都超出了范围。因此,当从堆栈中清除时,对字符串的这两个引用会立即从内存中清除。inputfor

对每个感兴趣对象的第三个引用存储在 中。当您调用 Map#remove 时,该元素(即对您的对象的引用)将从集合中删除(假设您特定的具体实现支持删除 — 确实支持删除)。StringSetStringMapMapHashSet

调用后,对对象的引用为零。如果没有指向对象(如 object)的引用,则该对象将成为垃圾回收的候选对象。最终,如果您的应用程序运行时间足够长,JVM 中的垃圾回收器将释放该对象所在的 RAM。Map#removeStringString

此外,如果对 ur 的引用超出范围,则地图将成为垃圾回收的候选对象。清除该映射后,将从内存中清除其包含的元素(即包含的引用)。与上面类似,随着对对象的最后一次引用被根除,该对象将成为最终垃圾回收的候选对象。MapStringString

最后,如果应用结束(如方法退出时所示),则应用使用的所有内存将被清除,所有引用和对象都会立即擦除。main


上述讨论的一个例外...... 是 Java 中的一种特殊类型。某些字符串对象可能被托管在特殊池中。Interning 意味着特定的字符串可能会从以前的使用中回收,而不是新实例化,并且可以保留以供将来使用,而不是垃圾回收。Interning 是可能的,因为每个对象都是不可变的。这种实习行为因特定 JVM 的实现细节而异。StringString