public long spillPartition(int partitionId) throws IOException {
    HashPartition partition = hashPartitions[partitionId];
    int inMemRowCount = partition.hashMap.getNumValues();
    if (inMemRowCount == 0) {
      LOG.warn("Trying to spill an empty hash partition! It may be due to " +
          "hive.auto.convert.join.noconditionaltask.size being set too low.");
    }

    File file = FileUtils.createLocalDirsTempFile(
        spillLocalDirs, "partition-" + partitionId + "-", null, false);
    OutputStream outputStream = new FileOutputStream(file, false);

    com.esotericsoftware.kryo.kryo5.io.Output output =
        new com.esotericsoftware.kryo.kryo5.io.Output(outputStream);
    Kryo kryo = SerializationUtilities.borrowKryo();
    try {
      LOG.info("Trying to spill hash partition " + partitionId + " ...");
      kryo.writeObject(output, partition.hashMap);  // use Kryo to serialize hashmap
      output.close();
      outputStream.close();
    } finally {
      SerializationUtilities.releaseKryo(kryo);
    }

    partition.hashMapLocalPath = file.toPath();
    partition.hashMapOnDisk = true;

    LOG.info("Spilling hash partition " + partitionId + " (Rows: " + inMemRowCount +
        ", Mem size: " + partition.hashMap.memorySize() + "): " + file);
    LOG.info("Memory usage before spilling: " + memoryUsed);

    long memFreed = partition.hashMap.memorySize();
    memoryUsed -= memFreed;
    LOG.info("Memory usage after spilling: " + memoryUsed);

    partition.rowsOnDisk = inMemRowCount;
    totalInMemRowCount -= inMemRowCount;
    partition.hashMap.clear();
    partition.hashMap = null;
    return memFreed;
  }
Move the hashtable of a specified partition from memory into local file system
@param partitionId the hashtable to be moved
@return amount of memory freed
ql/src/java/org/apache/hadoop/hive/ql/exec/persistence/HybridHashTableContainer.java