class_docstr: Wrap gc.collect to protect against excessively repeated calls.
  
  Allows to run throttled garbage collection in the workers as a
  countermeasure to e.g.: https://github.com/dask/zict/issues/19
  
  collect() does nothing when repeated calls are so costly and so frequent
  that the thread would spend more than max_in_gc_frac doing GC.
  
  warn_if_longer is a duration in seconds (10s by default) that can be used
  to log a warning level message whenever an actual call to gc.collect()
  lasts too long.
class_docstr_tok: ["Wrap","gc.collect","to","protect","against","excessively","repeated","calls",".","Allows","to","run","throttled","garbage","collection","in","the","workers","as","a","countermeasure","to","e.g",".",":","https",":","\/\/github.com\/dask\/zict\/issues\/19","collect","(",")","does","nothing","when","repeated","calls","are","so","costly","and","so","frequent","that","the","thread","would","spend","more","than","max_in_gc_frac","doing","GC",".","warn_if_longer","is","a","duration","in","seconds","(","10s","by","default",")","that","can","be","used","to","log","a","warning","level","message","whenever","an","actual","call","to","gc.collect","(",")","lasts","too","long","."]
code: def collect(self):
      # In case of non-monotonicity in the clock, assume that any Python
      # operation lasts at least 1e-6 second.
      MIN_RUNTIME = 1e-6
  
      collect_start = thread_time()
      elapsed = max(collect_start - self.last_collect, MIN_RUNTIME)
      if self.last_gc_duration / elapsed < self.max_in_gc_frac:
          self.logger.debug(
              "Calling gc.collect(). %0.3fs elapsed since previous call.",
              elapsed,
          )
          gc.collect()
          self.last_collect = collect_start
          self.last_gc_duration = max(
              thread_time() - collect_start, MIN_RUNTIME
          )
          if self.last_gc_duration > self.warn_if_longer:
              self.logger.warning(
                  "gc.collect() took %0.3fs. This is usually"
                  " a sign that some tasks handle too"
                  " many Python objects at the same time."
                  " Rechunking the work into smaller tasks"
                  " might help.",
                  self.last_gc_duration,
              )
          else:
              self.logger.debug(
                  "gc.collect() took %0.3fs", self.last_gc_duration
              )
      else:
          self.logger.debug(
              "gc.collect() lasts %0.3fs but only %0.3fs "
              "elapsed since last call: throttling.",
              self.last_gc_duration,
              elapsed,
          )
  
imports: from __future__ import annotations
  import gc
  import logging
  import threading
  from collections import deque
  import psutil
  from dask.utils import format_bytes
  from distributed.metrics import thread_time
label_desc: Use image node_id 2 for calling the ThrottledGC obj's underlying member method code with example usage: obj.collect() without return types