@Override
  public boolean mustEvict(EvictionCounters stats, InternalRegion region, int delta) {
    InternalCache cache = (InternalCache) region.getRegionService();
    boolean offheap = region.getAttributes().getOffHeap();
    boolean shouldEvict =
        cache.getInternalResourceManager().getMemoryMonitor(offheap).getState().isEviction();

    if (region instanceof BucketRegion) {
      return shouldEvict && ((BucketRegion) region).getSizeForEviction() > 0;
    }
    return shouldEvict && region.getRegionMap().sizeInVM() > 0;
  }
Okay, deep breath. Instead of basing the LRU calculation on the number of entries in the region
or on their "size" (which turned out to be incorrectly estimated in the general case), we use
the amount of memory currently in use. If the amount of memory current in use
{@linkplain Runtime#maxMemory} - {@linkplain Runtime#freeMemory} is greater than the overflow
threshold, then we evict the LRU entry.
geode-core/src/main/java/org/apache/geode/internal/cache/eviction/HeapLRUController.java