Как я могу изменить код, чтобы сборщик мусора удалил этот экземпляр из-за программы? - PullRequest
1 голос
/ 09 февраля 2020

В строке, помеченной // D, происходит одноразовое использование экземпляра объекта Scanner. но его память останется в куче до тех пор, пока программа играет (что навсегда). почему сборщик мусора не удалит этот экземпляр объекта? Как я могу изменить код, чтобы сборщик мусора удалил этот экземпляр из-за программы? спасибо

package Try;

import java.util.Random;
import java.util.Scanner;

public class Foo1 extends Thread {

    private int min_, max_;
    Foo1(int max, Integer min) {

    max_ = max;
    min_ = min.intValue();
    }

    public void run() {

        Random rand_gen = new Random();
        while(true) {
            try {
                Thread.sleep(rand_gen.nextInt(max_-min_) + min_);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
            System.out.println("you got new message");
        }
    }

    public static void main(String[] args){

        System.out.println("Insert 1 to start"); 

        Scanner sc = new Scanner(System.in); // D

        int i = sc.nextInt();

        if (i == 1) {
            Foo1 f1;
            int max = 1000;
            Integer min = new Integer(1000);
            Foo1 f2 = new Foo1(max, min);
            f1 = f2; // A
            f1.start();
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 09 февраля 2020

Вы можете удалить ссылку на сканер, установив для нее значение null, т. Е. sc = null.

-OR-

Если вам больше не нужен Scanner, вы можете закройте его после использования:

int i = sc.nextInt();
sc.close();

Еще лучше использовать try-with-resources следующим образом:

int i;
try (Scanner sc = new Scanner(System.in)) {
    i = sc.nextInt();
}

Обратите внимание, что sc.close() закрывает сканирует и освобождает ресурс, в то время как sc = null удаляет ссылку на сканер, но ресурс все еще может оставаться открытым.

Предупреждение: Никогда не закрывайте Scanner для System.in, если вы по-прежнему он нужен для большего количества входных данных от System.in, так как закрытие Scanner также закроет System.in. Рассмотрим следующий код:

String s;
System.out.print("Enter a text: ");
try (Scanner sc = new Scanner(System.in)) {
    s = sc.nextLine();
}

try (Scanner in = new Scanner(System.in)) {
    System.out.print("Enter another text: ");
    s = in.nextLine();
}

Попытка выполнить приведенный выше код приведет к:

Enter a text: hello
Enter another text: Exception in thread "main" java.util.NoSuchElementException: No line found
    at java.base/java.util.Scanner.nextLine(Scanner.java:1651)
    at Main.main(Main.java:14)
0 голосов
/ 09 февраля 2020

как я могу изменить код, чтобы сборщик мусора удалил этот экземпляр из-за программы?

Вам следует установить значение объекта null. Сборщик мусора освободит кучу памяти, используемую этим объектом.

public static void main(String[] args){

    System.out.println("Insert 1 to start"); 

    Scanner sc = new Scanner(System.in); // D

    int i = sc.nextInt();
    sc = null;

    if (i == 1) {
        Foo1 f1;
        int max = 1000;
        Integer min = new Integer(1000);
        Foo1 f2 = new Foo1(max, min);
        f1 = f2; // A
        f1.start();
    }
}

Причина, по которой он не удаляется автоматически в конце метода, заключается в том, что вы инициализируете его в методе main. Другими словами: основной метод останавливается, когда приложение останавливается.

...