private @Nullable ByteBuffer tryReclaimPageOfSize(int bufferSize,
                                                    int maxPagesToTry) {
    int dirtyPagesSkipped = 0;
    ThreadLocalRandom rnd = ThreadLocalRandom.current();
    for (int pagesTried = 0;
         pagesTried < maxPagesToTry && !memoryManager.hasFreeNativeCapacity(bufferSize);
         pagesTried++) {
      PageImpl candidateToReclaim = pagesToProbablyReclaim.poll();
      if (candidateToReclaim == null) {
        return null;//nothing more to reclaim
      }
      if (candidateToReclaim.usageCount() > 0) {
        continue;//page is in use by somebody (don't return it to the reclaim queue)
      }
      if (candidateToReclaim.isDirty()) {
        //We _prefer_ to not reclaim dirty pages here, on page allocation path, since .flush()
        //  creates unpredictable delays -- hence we _prefer_ to skip dirty pages, looking for
        //  non-dirty ones.
        //  But we can't skip all dirty pages, since it could be _no_ non-dirty pages
        //  available -- and scanning all pagesToProbablyReclaim to find it out is also a
        //  high cost. Hence, we skip dirty pages probabilistically: we accept N-th dirty page
        //  with probability N/maxPagesToTry (otherwise return dirty page to the queue end)
        if (dirtyPagesSkipped <= rnd.nextInt(maxPagesToTry)) {
          dirtyPagesSkipped++;
          pagesToProbablyReclaim.pushBack(candidateToReclaim);
          //MAYBE RC: also queue async .flush() for the page?
          continue;
        }
      }

      boolean succeed = candidateToReclaim.tryMoveTowardsPreTombstone(/*entombYoung: */false);
      if (succeed) {
        // > 1 thread could try to reclaim the page, but we win the race:
        ByteBuffer reclaimedBuffer = entombPageAndGetPageBuffer(candidateToReclaim);
        //'handoff': reuse reclaimed buffer immediately, if it's capacity is enough
        // (but not too much so we don't waste too much memory using huge buffer for small page)
        if (bufferSize <= reclaimedBuffer.capacity() && reclaimedBuffer.capacity() <= 2 * bufferSize) {
          reclaimedBuffer.clear().limit(bufferSize);
          return reclaimedBuffer;
        }
        else {
          reclaimPageBuffer(candidateToReclaim.pageSize(), reclaimedBuffer);
        }
      }
    }
    return null;
  }
private @Nullable ByteBuffer tryReclaimPageOfSize(int bufferSize,
                                                    int maxPagesToTry)