code: @VisibleForTesting
    void trimToNothing() {
      final List<Bucket<V>> bucketsToTrim;
  
      synchronized (this) {
        if (mPoolParams.fixBucketsReinitialization) {
          bucketsToTrim = refillBuckets();
        } else {
          bucketsToTrim = new ArrayList<>(mBuckets.size());
          final SparseIntArray inUseCounts = new SparseIntArray();
  
          for (int i = 0; i < mBuckets.size(); ++i) {
            final Bucket<V> bucket = mBuckets.valueAt(i);
            if (bucket.getFreeListSize() > 0) {
              bucketsToTrim.add(bucket);
            }
            inUseCounts.put(mBuckets.keyAt(i), bucket.getInUseCount());
          }
  
          legacyInitBuckets(inUseCounts);
        }
  
        // free up the stats
        mFree.reset();
        logStats();
      }
  
      // the pool parameters 'may' have changed.
      onParamsChanged();
  
      // Explicitly free all the values.
      // All the core data structures have now been reset. We no longer need to block other calls.
      // This is true even for a concurrent trim() call
      for (int i = 0; i < bucketsToTrim.size(); ++i) {
        final Bucket<V> bucket = bucketsToTrim.get(i);
        while (true) {
          // what happens if we run into an exception during the recycle. I'm going to ignore
          // these exceptions for now, and let the GC handle the rest of the to-be-recycled-bitmaps
          // in its usual fashion
          V item = bucket.pop();
          if (item == null) {
            break;
          }
          free(item);
        }
      }
    }
docs: Gets rid of all free values in the pool
  At the end of this method, mFreeSpace will be zero (reflecting that there are no more free
  values in the pool). mUsedSpace will however not be reset, since that's a reflection of the
  values that were allocated via the pool, but are in use elsewhere