code: func (kl *Kubelet) StartGarbageCollection() {
  	loggedContainerGCFailure := false
  	go wait.Until(func() {
  		if err := kl.containerGC.GarbageCollect(); err != nil {
  			klog.Errorf("Container garbage collection failed: %v", err)
  			kl.recorder.Eventf(kl.nodeRef, v1.EventTypeWarning, events.ContainerGCFailed, err.Error())
  			loggedContainerGCFailure = true
  		} else {
  			var vLevel klog.Level = 4
  			if loggedContainerGCFailure {
  				vLevel = 1
  				loggedContainerGCFailure = false
  			}
  
  			klog.V(vLevel).Infof("Container garbage collection succeeded")
  		}
  	}, ContainerGCPeriod, wait.NeverStop)
  
  	// when the high threshold is set to 100, stub the image GC manager
  	if kl.kubeletConfiguration.ImageGCHighThresholdPercent == 100 {
  		klog.V(2).Infof("ImageGCHighThresholdPercent is set 100, Disable image GC")
  		return
  	}
  
  	prevImageGCFailed := false
  	go wait.Until(func() {
  		if err := kl.imageManager.GarbageCollect(); err != nil {
  			if prevImageGCFailed {
  				klog.Errorf("Image garbage collection failed multiple times in a row: %v", err)
  				// Only create an event for repeated failures
  				kl.recorder.Eventf(kl.nodeRef, v1.EventTypeWarning, events.ImageGCFailed, err.Error())
  			} else {
  				klog.Errorf("Image garbage collection failed once. Stats initialization may not have completed yet: %v", err)
  			}
  			prevImageGCFailed = true
  		} else {
  			var vLevel klog.Level = 4
  			if prevImageGCFailed {
  				vLevel = 1
  				prevImageGCFailed = false
  			}
  
  			klog.V(vLevel).Infof("Image garbage collection succeeded")
  		}
  	}, ImageGCPeriod, wait.NeverStop)
  }
docs: // StartGarbageCollection starts garbage collection threads.