private void discardBlocksBasedOnFreeLists(
      int freeListIx, int startArenaIx, int arenaCount, DiscardContext ctx) {
    defragCounters[freeListIx].incrementAndGet();
    // The free list level the blocks from which we need to merge.
    final int mergeListIx = freeListIx - 1;

    // Try to allocate using base-buffer approach from each arena.
    int arenaIx = startArenaIx;
    do {
      Arena arena = arenas[arenaIx];
      // Reserve blocks in this arena that would empty the sections of requisite size.
      arena.reserveDiscardBlocksBasedOnFreeList(mergeListIx, ctx);
      // Discard the blocks.
      discardFromCtxBasedOnFreeList(arena, ctx, freeListIx);

      if (ctx.remainingToFind == 0) return; // Reserved as much as we needed.
      ctx.resetBetweenArenas();
      arenaIx = getNextIx(arenaIx, arenaCount, 1);
    } while (arenaIx != startArenaIx);
  }
The headers from abandoned moved attempts that cannot yet be returned to the
free lists, or unlocked due to some lock being held and deadlock potential.
llap-server/src/java/org/apache/hadoop/hive/llap/cache/BuddyAllocator.java