使用 Finalize 函数,当我将一个对象指向 null
时,尽管它正确递增,但它并没有递减。我还提到了垃圾收集器,它会听自己的声音,我知道,但为什么它不起作用。我使用的是java jdk 1.8.0。
public class student{
private String name; private int roll; private static int count = 0;
//setters
public void setname(String nam){
name = nam;
}
public void setroll(int rol){
roll = rol;
}
//getters
public String getname(){
return name;
}
public int getroll(){
return roll;
}
public static int getCount(){
return count;
}
//default constructor
public student(){
name = "default";
roll = 9999;
count += 1;
}
//parameterized constructor
public student(String nam, int rol){
setname(nam); setroll(rol);
count += 1;
}
//copy constructor
public student(student s){
name = s.name; roll = s.roll;
count += 1;
}
//methods to print on console
public void print(){
System.out.println("name: " + name + "\n" + "Roll Num: " + roll);
}
// overriding finalize method of Object class
public void finalize(){
count -= 1;
}
}
//main function
public class clsnew{
public static void main(String args[]){
System.out.println("nuber of students" + student.getCount());
student s1 = new student("Ahmad", 170404873);
student s2 = new student();
s1.print(); //printing using parameterized constructor
s2.print(); //printing using default constructor
System.out.println("number of students" + student.getCount());
s2.setname("Ali"); s2.setroll(200404230);
System.out.print("s2: Name = "+s2.getname());
System.out.println("Roll number: "+s2.getroll());
student s3 = new student(s2);
s2.print(); s3.print();
System.out.println("number of students" + student.getCount());
s2 = null;
System.gc();
int c = student.getCount();
System.out.println("number of students" + student.getCount());
}
}
最佳答案
首先,您永远不应该编写依赖于垃圾收集器的应用程序。此外,即使您需要与垃圾收集器交互,也应该避免 finalize()
。
出于教育目的,您必须了解以下事项:
最终确定不是即时的。
System.gc()
不能保证识别特定的死对象,甚至根本没有效果,但是当它确实发生时,它可能只会将对象排入队列以进行终结,所以到了>System.gc()
返回,终结可能尚未完成。它甚至可能还没有开始。由于终结器在任意线程中运行,因此需要线程安全更新。
进行以下更改:
将
private static int count = 0;
更改为
private static final AtomicInteger count = new AtomicInteger();
,在每个构造函数中进一步
count += 1;
到count.incrementAndGet();
和count -= 1;
到finalize()
方法中的count.decrementAndGet();
。和
getCount()
到public static int getCount(){ return count.get(); }
将
System.gc();
更改为System.gc(); Thread.sleep(100);
您可以使用
try...catch
block 包围sleep
调用,或者更改main
方法的声明,添加抛出 InterruptedException
然后,您可以观察 student
实例的最终确定。为了说明依赖垃圾收集的程序的反直觉行为,我建议再次运行该程序,现在使用 -Xcomp
选项。
当您有 JDK 11 或更高版本时,您还可以使用以下命令再次运行
-XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC
。
关于java - 尝试减少 java jdk 1.8.0 中的静态计数变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60716828/