MyCATApache/Mycat-Server · error · IllegalStateException

Have already allocated a maximum of

Error message

Have already allocated a maximum of ${pageTableSize} pages

What it means

DataNodeMemoryManager maintains a fixed-size page table (PAGE_TABLE_SIZE entries) mapping page numbers to allocated MemoryBlocks. When allocatePage cannot find a free page number below PAGE_TABLE_SIZE, it releases the just-acquired memory and throws IllegalStateException — the consumer has exhausted the page table.

Solutions

  1. Free pages with `memoryManager.freePage(page, consumer)` when no longer needed; audit for leaked allocations.
  2. Reuse/pool pages instead of allocating a new page per record or batch.
  3. Increase PAGE_TABLE_SIZE if the workload legitimately needs more live pages (rebuild with a larger constant).
  4. Use larger pages so fewer page allocations are needed for the same data volume.

Example fix

// before
MemoryBlock p = mm.allocatePage(size, consumer);
// p never freed
// after
MemoryBlock p = mm.allocatePage(size, consumer);
try {
  // use page
} finally {
  mm.freePage(p, consumer);
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (memoryManager.getPageCountEstimate() >= PAGE_TABLE_SIZE_LIMIT) {
  // consolidate into fewer, larger pages before allocating more
  consolidatePages();
}

Try / catch

try {
  page = memoryManager.allocatePage(size, consumer);
} catch (IllegalStateException e) {
  // page table exhausted — free stale pages or switch to a larger-page strategy
  freeUnusedPages(consumer);
  page = memoryManager.allocatePage(size, consumer);
}

Prevention

When it happens

Trigger: Calling allocatePage so many times (without freeing pages) that allocatedPages has every bit set; leaking pages across many allocatePage calls within one task/consumer.

Common situations: Long-running tasks allocating many small pages instead of reusing them; code paths that forget to freePage; consumers allocating a page per record on huge datasets.

Related errors


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

Appendix: source

Thrown at src/main/java/io/mycat/memory/unsafe/memory/mm/DataNodeMemoryManager.java:254

     */
    long acquired = 0;
    try {
      acquired = acquireExecutionMemory(size,tungstenMemoryMode, consumer);
    } catch (InterruptedException e) {
      logger.error(e.getMessage());
    }

    if (acquired <= 0) {
      return null;
    }

    final int pageNumber;

    synchronized (this) {
      pageNumber = allocatedPages.nextClearBit(0);
      if (pageNumber >= PAGE_TABLE_SIZE) {
        releaseExecutionMemory(acquired, tungstenMemoryMode, consumer);
        throw new IllegalStateException(
          "Have already allocated a maximum of " + PAGE_TABLE_SIZE + " pages");
      }
      allocatedPages.set(pageNumber);
    }



    MemoryBlock page = null;

    try {
      page = memoryManager.tungstenMemoryAllocator().allocate(acquired);
    } catch (OutOfMemoryError e) {
      logger.warn("Failed to allocate a page ({} bytes), try again.", acquired);
      // there is no enough memory actually, it means the actual free memory is smaller than
      // MemoryManager thought, we should keep the acquired memory.
      synchronized (this) {
        acquiredButNotUsed += acquired;
        allocatedPages.clear(pageNumber);

View on GitHub (pinned to 65f8d8beb7)