本地字符串扫描程序什么时候收集垃圾?

时间:2015-02-04 19:08:42

标签: java garbage-collection java.util.scanner

假设我有String s,我想在Builder中使用Scanner通过此方法迭代它:

private void scan(String s){    
    Scanner scanner = new Scanner(s);
    while (scanner.hasNext()){
        //do something
    }
}

我们假设s是一个变量,是另一个Object的一部分。

public class Person{
    String name;
    //rest of code
}

现在让我们假设这个对象存储在一个Singleton中,该Singleton存储数据以便在程序的生命周期内随时可用

public class Singleton{
    private List<Person> list = new ArrayList<>();
    //rest of code
}

我的问题是:scanner完成运行后scan(String s)会发生什么?它会保持活力还是会在达到其范围后收集,从而释放资源?如果没有收集,如果我将scan(String s)更改为:

会发生什么
private void scan(String s){    
    Scanner scanner = new Scanner(s);
    while (scanner.hasNext()){
        //do something
    }
    scanner.close();
}

或者后一种形式是否应该首选?

2 个答案:

答案 0 :(得分:1)

对于Scanner上的String,扫描程序将有StringReader作为其源,它将引用字符串,但不会引用扫描程序本身。由于StringReader纯粹是在内存中,因此不需要关闭或清理。但是,关闭它没有任何害处,但是如果你确实选择关闭它,你应该将调用关闭在finally块中,或者通过使用try-with-resources使其隐式:

Scanner scanner = new Scanner(s);
try {
    while (scanner.hasNext()) {
        // do something
    }
} finally {
    scanner.close();
}

或者:

try (Scanner scanner = new Scanner(s)) {
    while (scanner.hasNext()) {
        // do something
    }
} // close will be implicitly called

规则是,您应该始终关闭您打开的任何内容,以确保清理资源。

对于文件上的扫描仪,关闭它非常重要。

对于System.in上的扫描程序,您没有打开 System.in,因此关闭它不是您的责任。

对于字符串上的扫描程序,或者从ByteArrayInputStreamStringReader进行阅读时,没有任何有意义的资源可以关闭,但它可能是最好的以一种关闭将被调用的方式写东西,以防你以后再切换它来读取文件(或者只是为了养成习惯)。

关于垃圾收集的问题,你永远不能真正说出什么时候会收集垃圾。如果您的程序永远不会运行内存不足,垃圾收集器甚至可能无法运行。但是既然String和StringReader都没有维护对Scanner的引用,只要方法scan(String)中的局部变量对它的引用消失,它就会符合条件进行垃圾回收。回报。

答案 1 :(得分:0)

始终首选关闭文件上的扫描程序,以便可以确定地清理文件资源。

可以在丢弃扫描仪后清除字符串,假设它没有在其他任何地方引用。

对于扫描仪,我建议使用try-with-resource

try (Scanner scanner = new Scanner(filename)) {
    while (scanner.hasNext()){
        //do something
    }
}