public void put(K key, T value) {
    if (estimatedPayloadSize == 0) {
      this.estimatedPayloadSize =
          keySizeEstimator.sizeEstimate(key) + valueSizeEstimator.sizeEstimate(value);
    } else if (++putCount % RECORDS_TO_SKIP_FOR_ESTIMATING == 0) {
      this.estimatedPayloadSize =
          (long)
              (this.estimatedPayloadSize * 0.9
                  + (keySizeEstimator.sizeEstimate(key) + valueSizeEstimator.sizeEstimate(value))
                      * 0.1);
      this.currentInMemoryMapSize = this.memoryMap.size() * this.estimatedPayloadSize;
    }

    if (memoryMap.containsKey(key)) {
      memoryMap.put(key, value);
      return;
    }

    if (this.currentInMemoryMapSize < maxInMemorySizeInBytes) {
      if (memoryMap.put(key, value) == null) {
        currentInMemoryMapSize += this.estimatedPayloadSize;
      }
    } else {
      if (!diskBasedMap.isPresent()) {
        diskBasedMap =
            Optional.of(new SimpleSpilledMap<>(keySerializer, valueSerializer, backendBaseDir));
      }
      diskBasedMap.get().put(key, value);
    }
  }
Approximate memory footprint of the in-memory map.
amoro-format-iceberg/src/main/java/org/apache/amoro/utils/map/SimpleSpillableMap.java