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
- Reduce the requested array size (smaller batches, cap sorter size) so it fits in available execution memory.
- Increase execution memory for the process/task (allocator/memory-manager configuration).
- Reduce concurrency so fewer consumers compete for the same execution memory pool.
- 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
- Size long arrays against available execution memory, not dataset size.
- Cap sorter/array growth and spill earlier.
- Reduce concurrent tasks sharing the memory pool.
- Increase execution memory limits for large workloads.
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
- error while calling spill() on
- error while calling spill() on
- Initial capacity exceeds maximum capacity of
- Page size cannot exceed
- Cannot allocate a page with more than
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)