Ниже приведена моя Программа для тестирования жизни статических переменных.
public class A {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new B());
thread.start();
while(thread.isAlive()){
Thread.sleep(1000);
}
System.gc();
Thread thread2 = new Thread(new B());
thread2.start();
while(thread2.isAlive()){
Thread.sleep(1000);
}
System.gc();
System.out.println("Last One :: " + B.name);
}
}
B.java
public class B implements Runnable{
public static int name;
@Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("Finalize called");
}
@Override
public void run() {
for(int i=0;i<10;i++){
name++;
}
System.out.println("Class B :: " + name);
}
}
Вывод:
Class B :: 10
Finalize called
Class B :: 20
Finalize called
Last One :: 20
Первый поток создает новый экземпляр B, запускает указатель приращения потока переменной имени, а основной поток ожидает завершения потока и вызывает GC.Again. Я повторяю процесс. Тем не менее старый указатель поддерживается даже после создания потока, создающего экземпляр B завершается, и GC запускается 2 раза. Как хранятся статические переменные в памяти и как долго они сохраняются в памяти?
Процитировано из другого поста:
Как все сказали в ответ, что статические переменные являются переменными класса. Они остаются в памяти, пока класс не выгрузится из JVM.
Может быть, это DUP этого одного.
B.name
не связано с каким-либо конкретным объектом: это переменная класса, и поэтому она остается доступной до тех пор, пока класс остается доступным (в данном случае это означает время жизни вашей программы).
Кроме того, стоит отметить (хотя это не связано с этой конкретной проблемой), что System.gc()
является рекомендацией, а не гарантией того, что сбор мусора начнется немедленно и завершится до того, как будет выполнена следующая строка в вашей программе.