对于java,如何释放HashSet中1个元素的内存?

问题描述 投票:0回答:1

如果我有这样的代码:

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 memory-management java.util.scanner hashset
1个回答
0
投票

在您的特定代码中,每个

String
对象只有三个引用:

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

前两个,即

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

对每个感兴趣的

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

调用

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


上述讨论的一个例外...

String
是Java中的一种特殊类型。某些字符串对象可能会被“驻留”在一个特殊的池中。驻留意味着特定的字符串可能会从以前的使用中回收而不是新实例化,并且可能会保留以供将来使用而不是被垃圾收集。此行为因特定 JVM 的实现细节而异。

© www.soinside.com 2019 - 2024. All rights reserved.