Попытка уменьшить мою переменную подсчета stati c в java jdk 1.8.0 - PullRequest
0 голосов
/ 17 марта 2020

Используя функцию финализации, когда я указываю объект на 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());

    }
}

1 Ответ

1 голос
/ 18 марта 2020

Прежде всего, вы никогда не должны писать приложения, опираясь на сборщик мусора. Кроме того, даже если вам необходимо взаимодействие с сборщиком мусора, вам следует избегать finalize().

. В образовательных целях вы должны знать следующее:

  • Финализация не мгновенная. System.gc() не гарантирует, что он идентифицирует конкретный мертвый объект или даже оказывает какое-либо влияние, но когда это происходит, он может ставить в очередь только объект для завершения, поэтому к моменту возврата System.gc() завершение может еще не завершиться , Возможно, он еще не запустился.

  • Поскольку финализатор работает в произвольном потоке, он требует обновлений, безопасных для потока.

Сделайте следующее изменения:

  • Изменение private static int count = 0; на
    private static final AtomicInteger count = new AtomicInteger();,

    далее count += 1; на count.incrementAndGet(); в каждом конструкторе
    и count -= 1; до count.decrementAndGet(); в методе finalize().

    и getCount() до

      public static int getCount(){
          return count.get();
      }
    
  • Измените System.gc(); на

      System.gc();
      Thread.sleep(100);
    

    Вы можете окружить вызов sleep блоком try...catch или изменить объявление метода main, добавив throws InterruptedException

Затем вы можете наблюдать завершение student экземпляр. Чтобы проиллюстрировать нелогичное поведение программ, полагающихся на сборку мусора, я рекомендую снова запустить программу, теперь с опцией -Xcomp.

Если у вас JDK 11 или новее, вы можете также выполнить еще один запуск с
-XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC.

...