Using finalize function, when I point an object to null it’s not decrementing although it is incrementing properly. I also mentioned garbage collector which will listen to its own self, I know but why it’s not working. I am using 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());
}
}
First of all, you should never write applications relying on the garbage collector. Further, even if you need interaction with the garbage collector, you should avoid
finalize().For educational purposes, you have to be aware of the following things:
Finalization is not instantaneous.
System.gc()is not guaranteed to identify a particular dead object, or even have an effect at all, but when it does, it may only enqueue the object for finalization, so by the timeSystem.gc()returns, finalization might not have finished yet. It even might not have started yet.Since the finalizer runs in an arbitrary thread, it requires thread safe updates.
Make the following changes:
Change
private static int count = 0;toprivate static final AtomicInteger count = new AtomicInteger();,further
count += 1;tocount.incrementAndGet();in each constructorand
count -= 1;tocount.decrementAndGet();in thefinalize()method.And
getCount()toChange
System.gc();toYou may surround the
sleepcall with atry...catchblock or change the declaration of themainmethod addingthrows InterruptedExceptionThen, you may observe the finalization of a
studentinstance. To illustrate the counter-intuitive behavior of programs relying on garbage collection, I recommend running the program again, now with the-Xcompoption.When you have JDK 11 or newer, you might also do a another run with
-XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC.