45    private const GC_THRESHOLD_TRIGGER = 100;
 
   46    private const GC_THRESHOLD_MAX = 1_000_000_000;
 
   47    private const GC_THRESHOLD_DEFAULT = 10_001;
 
   48    private const GC_THRESHOLD_STEP = 10_000;
 
   50    private int $threshold = self::GC_THRESHOLD_DEFAULT;
 
   51    private int $collectionTimeTotalNs = 0;
 
   52    private int $runs = 0;
 
   54    private \Logger $logger;
 
   57    public function __construct(
 
   62        $this->logger = new \PrefixedLogger($logger, 
"Cyclic Garbage Collector");
 
   63        $this->timings = 
new TimingsHandler(
"Cyclic Garbage Collector", $parentTimings);
 
   66    private function adjustGcThreshold(
int $cyclesCollected, 
int $rootsAfterGC) : 
void{
 
   71        if($cyclesCollected < self::GC_THRESHOLD_TRIGGER || $rootsAfterGC >= $this->threshold){
 
   72            $this->threshold = min(self::GC_THRESHOLD_MAX, $this->threshold + self::GC_THRESHOLD_STEP);
 
   73        }elseif($this->threshold > self::GC_THRESHOLD_DEFAULT){
 
   74            $this->threshold = max(self::GC_THRESHOLD_DEFAULT, $this->threshold - self::GC_THRESHOLD_STEP);
 
   78    public function getThreshold() : 
int{ 
return $this->threshold; }
 
   80    public function getCollectionTimeTotalNs() : 
int{ 
return $this->collectionTimeTotalNs; }
 
   82    public function maybeCollectCycles() : 
int{
 
   83        $rootsBefore = gc_status()[
"roots"];
 
   84        if($rootsBefore < $this->threshold){
 
   88        $this->timings->startTiming();
 
   90        $start = hrtime(
true);
 
   91        $cycles = gc_collect_cycles();
 
   94        $rootsAfter = gc_status()[
"roots"];
 
   95        $this->adjustGcThreshold($cycles, $rootsAfter);
 
   97        $this->timings->stopTiming();
 
   99        $time = $end - $start;
 
  100        $this->collectionTimeTotalNs += $time;
 
  102        $this->logger->info(sprintf(
 
  103            "Run #%d took %s ms (%s -> %s roots, %s cycles collected) - cumulative GC time: %s ms",
 
  105            number_format($time / 1_000_000, 2),
 
  109            number_format($this->collectionTimeTotalNs / 1_000_000, 2)