如果我有这样的代码:
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() 函数删除映射中的所有条目,这是我不想要的。
在您的特定代码中,每个
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 的实现细节而异。