@Nullable
  private synchronized ArrayList<Entry<K, V>> trimExclusivelyOwnedEntries(int count, int size) {
    count = Math.max(count, 0);
    size = Math.max(size, 0);
    // fast path without array allocation if no eviction is necessary
    if (this.mExclusiveEntries.getCount() <= count && mExclusiveEntries.getSizeInBytes() <= size) {
      return null;
    }
    ArrayList<Entry<K, V>> oldEntries = new ArrayList<>();
    while (this.mExclusiveEntries.getCount() > count || mExclusiveEntries.getSizeInBytes() > size) {
      @Nullable K key = mExclusiveEntries.getFirstKey();
      if (key == null) {
        if (mIgnoreSizeMismatch) {
          mExclusiveEntries.resetSize();
          break;
        }
        throw new IllegalStateException(
            String.format(
                "key is null, but exclusiveEntries count: %d, size: %d",
                this.mExclusiveEntries.getCount(), mExclusiveEntries.getSizeInBytes()));
      }
      mExclusiveEntries.remove(key);
      oldEntries.add(mCachedEntries.remove(key));
    }
    return oldEntries;
  }
Removes the exclusively owned items until there is at most <code>count</code> of them and they
occupy no more than <code>size</code> bytes.

<p>This method returns the removed items instead of actually closing them, so it is safe to be
called while holding the <code>this</code> lock.
imagepipeline-base/src/main/java/com/facebook/imagepipeline/cache/LruCountingMemoryCache.java