code: public static void startFinalizer(
        Class<?> finalizableReferenceClass,
        ReferenceQueue<Object> queue,
        PhantomReference<Object> frqReference) {
      /*
       * We use FinalizableReference.class for two things:
       *
       * 1) To invoke FinalizableReference.finalizeReferent()
       *
       * 2) To detect when FinalizableReference's class loader has to be garbage collected, at which
       * point, Finalizer can stop running
       */
      if (!finalizableReferenceClass.getName().equals(FINALIZABLE_REFERENCE)) {
        throw new IllegalArgumentException("Expected " + FINALIZABLE_REFERENCE + ".");
      }
  
      Finalizer finalizer = new Finalizer(finalizableReferenceClass, queue, frqReference);
      String threadName = Finalizer.class.getName();
      Thread thread = null;
      if (bigThreadConstructor != null) {
        try {
          boolean inheritThreadLocals = false;
          long defaultStackSize = 0;
          thread =
              bigThreadConstructor.newInstance(
                  (ThreadGroup) null, finalizer, threadName, defaultStackSize, inheritThreadLocals);
        } catch (Throwable t) {
          logger.log(
              Level.INFO, "Failed to create a thread without inherited thread-local values", t);
        }
      }
      if (thread == null) {
        thread = new Thread((ThreadGroup) null, finalizer, threadName);
      }
      thread.setDaemon(true);
  
      try {
        if (inheritableThreadLocals != null) {
          inheritableThreadLocals.set(thread, null);
        }
      } catch (Throwable t) {
        logger.log(
            Level.INFO,
            "Failed to clear thread local values inherited by reference finalizer thread.",
            t);
      }
  
      thread.start();
    }
docs: Starts the Finalizer thread. FinalizableReferenceQueue calls this method reflectively.
  
  @param finalizableReferenceClass FinalizableReference.class.
  @param queue a reference queue that the thread will poll.
  @param frqReference a phantom reference to the FinalizableReferenceQueue, which will be queued
  either when the FinalizableReferenceQueue is no longer referenced anywhere, or when its
  close() method is called.