Java 9以降のゴミ回収の具体的な使い方


1:finalize()方法
finallize()の方法はObject類の方法で、クラスがGCに回収される時にいくつかの処理操作をするために用いられますが、JVMはfinalize(0)の方法が必ず実行されるとは保証できません。
finalize()メソッドの呼び出しタイミングは不確実性があるので、一つのオブジェクトから到達不可能になり始め、finalize()方法まで実行され、かかる時間はこの時間のどれでも長い。私たちはfinalize()方法に依存して適時に占有された資源を回収できません。可能な限り、私たちが資源を使い果たす前に、gcはまだ触発されていません。したがって、通常のやり方は表示されたclose()方法を提供して、クライアントが手動で起動するためです。
したがって、一般的にはfinalizeの方法は提案されていません。JDK 9はすでに廃止されています。
-欠点をまとめる
1:finalizeメカニズム自体に問題があります。
2:finalize機構は性能問題、デッドロック及びスレッドの吊下げを引き起こす可能性があります。
3:finalize中のエラーがメモリ漏れを引き起こす可能性があります。必要な時でなければ、ゴミの回収をキャンセルすることはできません。また、finalizeオブジェクトの実行順序は指定されていません。また、finlizeの実行時間は保証できません。 
これらの場合、オブジェクト呼び出しは無期限延期となります。
-finalizeメソッドを観察し、クラスのライフサイクルを延長します。

class User{
 
 public static User user = null;

 @Override
 protected void finalize() throws Throwable {
 System.out.println("User-->finalize()");
 user = this;
 }
 
}

public class FinalizerTest {
 public static void main(String[] args) throws InterruptedException {
 User user = new User();
 user = null;
 System.gc();
 Thread.sleep(1000);
 
 user = User.user;
 System.out.println(user != null);//true
 
 user = null;
 System.gc();
 Thread.sleep(1000);
 System.out.println(user != null);//false
 }
}

-JDk 9以前のゴミ回収コード

public class Finalizer {

 @Override
 protected void finalize() throws Throwable {
  System.out.println("Finalizer-->finalize()");
 }

 public static void main(String[] args) {
  Finalizer f = new Finalizer();
  f = null;
  
  System.gc();//    gc
 }
}
//   Finalizer-->finalize()
2:Clearer類の使用
プロフィール:
Java 9以降に最終クラスClearを提供して代替実現します。

package Thread;

import java.lang.ref.Cleaner;

public class CleaningExample implements AutoCloseable{

  
  private final static Cleaner CLEANER=Cleaner.create();//          
  
  static class State implements Runnable{ //         
    State() {
      System.out.println("init");
    }
    @Override
    public void run() {
      System.out.println("close");
    }
  }
  
  private final State state;
  private final Cleaner.Cleanable  cleanable; // clearner               
  
  public CleaningExample() {
    super();
    this.state = new State();
    this.cleanable=CLEANER.register(this, state); //                    
  }

  @Override
  public void close() throws Exception {
    cleanable.clean(); //      
  }
  
  public static void main(String[] args) {
    while(true) {
      new CleaningExample();
    }
  }

}

上記では、
Clearerは最終クラスで書き換えられません。内部方法は基本的に静的な方法で提供されます。  例の上の方法を把握すればいいです。
重点的に指摘する
 static class State implemens Runnable
 直接クラスで定義して実装する場合は、静的な内部クラス(強制)を提供しなければなりません。いいえ、回収できません。   原因(:一般内部クラスの局部内部類は外部類に依存(引用)しており、メモリの放出は実際には実現できない)
直接定義する外部カテゴリを選択できます。  Cleeanable
いつ回収されますか?
*1.登録されたObjectは幻の引用状態にあります。
*2.明示的にcleanを呼び出す方法
実例(模版)

public class CleaningExample extends Thread implements AutoCloseable {
  private final static Cleaner CLEANER = Cleaner.create();
  private final State state;
  private final Cleaner.Cleanable cleanable;
  
  public CleaningExample() {
    this.state = new State();
    this.cleanable = CLEANER.register(this, state);
  }

  @Override
  public void close() throws Exception {
    cleanable.clean();
  }
  
  @SuppressWarnings("resource")
  public static void main(String[] args) {
    while (true) {
      CleaningExample example = new CleaningExample();
    }
  }
  //       
  @Override
  public void run() {
    System.out.println("            ................");
  }
  //     
  class State implements Runnable {
    State() {
      System.out.println("<--- init --->");
    }
    @Override
    public void run() {
      System.out.println("<--- close --->");
    }
  }
}

基礎を実現する

  /**
   * Heads of a CleanableList for each reference type.
   */
  final PhantomCleanable<?> phantomCleanableList;

  final WeakCleanable<?> weakCleanableList;

  final SoftCleanable<?> softCleanableList;

  // The ReferenceQueue of pending cleaning actions
  final ReferenceQueue<Object> queue;

CleeanerImplクラスでclearnerクラスの最終的な実現を行い、定義されたこれらのフィールドを見て、彼の基本原理を基本的に明確にしました。
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。