MyCATApache/Mycat-Server · critical · OutOfMemoryError

Unable to acquire bytes of memory, got

Error message

Unable to acquire ${required} bytes of memory, got ${got}

What it means

MemoryConsumer.allocateLongArray tries to acquire `required` bytes of execution memory and allocate a page for a LongArray. When the memory manager cannot provide a page large enough even after spilling, it frees any partial page, dumps memory usage, and throws OutOfMemoryError reporting how many bytes were requested vs. actually obtained.

Solutions

  1. Reduce the requested array size (smaller batches, cap sorter size) so it fits in available execution memory.
  2. Increase execution memory for the process/task (allocator/memory-manager configuration).
  3. Reduce concurrency so fewer consumers compete for the same execution memory pool.
  4. Catch OutOfMemoryError and fall back to a disk-based (spilling) implementation instead of an in-memory long array.

Example fix

// before
LongArray arr = consumer.allocateLongArray(numRecords * 2);
// after
long required = numRecords * 2 * 8L;
if (required > availableExecutionMemory()) {
  // shrink or spill instead
  numRecords = maxRecordsThatFit(availableExecutionMemory());
}
LongArray arr = consumer.allocateLongArray(numRecords * 2);
Defensive patterns

Strategy: try-catch

Validate before calling

long requiredBytes = numLongs * 8L;
if (requiredBytes > memoryManager.getAvailableExecutionMemory()) {
  numLongs = (int) (memoryManager.getAvailableExecutionMemory() / 8L);
}

Try / catch

try {
  LongArray arr = consumer.allocateLongArray(numLongs);
} catch (OutOfMemoryError e) {
  // fall back to a spilling/disk-backed sorter
  sorter = new ExternalSorter(...);
}

Prevention

When it happens

Trigger: Calling allocateLongArray(required) on a MemoryConsumer (e.g. UnsafeInMemorySorter growth) when the DataNodeMemoryManager cannot grant `required` bytes of execution memory after spilling all consumers.

Common situations: Sorters/pointers arrays growing on datasets larger than available execution memory; too many concurrent tasks sharing a fixed memory pool; under-provisioned executor memory.

Related errors


AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11). Data as JSON: /api/errors/5e6a6935de2f5386. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/io/mycat/memory/unsafe/memory/mm/MemoryConsumer.java:92

   * @return the amount of released memory in bytes
   * @throws IOException
   */
  public abstract long spill(long size, MemoryConsumer trigger) throws IOException;

  /**
   * Allocates a LongArray of `size`.
   */
  public LongArray allocateLongArray(long size) {
    long required = size * 8L;
    MemoryBlock page = dataNodeMemoryManager.allocatePage(required,this);
    if (page == null || page.size() < required) {
      long got = 0;
      if (page != null) {
        got = page.size();
        dataNodeMemoryManager.freePage(page, this);
      }
      dataNodeMemoryManager.showMemoryUsage();
      throw new OutOfMemoryError("Unable to acquire " + required + " bytes of memory, got " + got);
    }
    used += required;
    return new LongArray(page);
  }

  /**
   * Frees a LongArray.
   */
  public void freeLongArray(LongArray array) {
    freePage(array.memoryBlock());
  }

  public CharArray allocateCharArray(long size) {
    long required = size * 2L;
    MemoryBlock page = dataNodeMemoryManager.allocatePage(required,this);
    if (page == null || page.size() < required) {
      long got = 0;
      if (page != null) {

View on GitHub (pinned to 65f8d8beb7)