@Override
  public synchronized boolean evict(AtomicLong releaseNodeNum, AtomicLong releaseMemorySize) {
    lockManager.globalReadLock();
    try {
      ICachedMNode node = null;
      CacheEntry cacheEntry = null;
      List<ICachedMNode> evictedMNodes = new ArrayList<>();
      boolean isSuccess = false;
      while (!isSuccess) {
        node = nodeCache.getPotentialNodeTobeEvicted();
        if (node == null) {
          break;
        }
        lockManager.threadReadLock(node.getParent(), true);
        try {
          cacheEntry = getCacheEntry(node);
          // the operation that may change the cache status of a node should be synchronized
          synchronized (cacheEntry) {
            if (cacheEntry.isPinned()
                || cacheEntry.isVolatile()
                || cacheEntry.hasVolatileDescendant()) {
              // since the node could be moved from cache to buffer after being taken from cache
              // this check here is necessary to ensure that the node could truly be evicted
              continue;
            }

            getBelongedContainer(node).evictMNode(node.getName());
            if (node.isMeasurement()) {
              String alias = node.getAsMeasurementMNode().getAlias();
              if (alias != null) {
                node.getParent().getAsDeviceMNode().deleteAliasChild(alias);
              }
            }
            nodeCache.removeFromNodeCache(getCacheEntry(node));
            node.setCacheEntry(null);
            evictedMNodes.add(node);
            isSuccess = true;
          }
        } finally {
          lockManager.threadReadUnlock(node.getParent());
        }
      }

      if (node != null) {
        collectEvictedMNodes(node, evictedMNodes);
      }

      int sz = memoryStatistics.releaseMemResource(evictedMNodes);
      releaseMemorySize.addAndGet(sz);
      releaseNodeNum.addAndGet(evictedMNodes.size());
      return !evictedMNodes.isEmpty();
    } finally {
      lockManager.globalReadUnlock();
    }
  }
Choose an evictable node from nodeCache and evicted all the cached node in the subtree it
represented.

@return whether evicted any MNode successfully
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/pbtree/memory/MemoryManager.java