MyCATApache/Mycat-Server · critical · OutOfMemoryError
Not enough memory to grow pointer array
Error message
Not enough memory to grow pointer array
What it means
UnsafeInMemorySorter.expandPointerArray throws OutOfMemoryError when the replacement LongArray offered for the sorter's pointer/prefix array is smaller than the current one. Growth must never shrink capacity, so the method fails fast rather than truncating in-flight sort records.
Solutions
- Free execution memory (unpersist/spill cached data) before the sort so the growth allocation can be full-sized.
- Increase execution memory limits (memory fraction / heap size) for the process.
- Fix callers to allocate the new array at >= 2x current size and assert size before calling.
- Reduce concurrent sorters/tasks competing for the same memory pool.
- Enable spilling earlier so the in-memory sorter needs fewer expansions.
Example fix
// before LongArray newArr = allocate(someSize); sorter.expandPointerArray(newArr); // after long newSize = Math.max(sorter.getCurrentArraySize() * 2, minRequired); LongArray newArr = allocate(newSize); if (newArr.size() < sorter.getCurrentArraySize()) spillAndRetry(); sorter.expandPointerArray(newArr);
Defensive patterns
Strategy: try-catch
Validate before calling
LongArray grow = tryAllocate(current * 2);
if (grow == null || grow.size() < current) { spill(); return; }
sorter.expandPointerArray(grow); Try / catch
try { sorter.expandPointerArray(newArray); } catch (OutOfMemoryError e) { spillCurrentSorter(); freeMemory(); retryExpansion(); } Prevention
- Reserve execution memory headroom before large sorts
- Spill earlier instead of relying on repeated array growth
- Cap concurrent in-memory sorters
- Monitor allocator failures in memory manager metrics
When it happens
Trigger: Calling expandPointerArray with a newly allocated LongArray whose size < current array.size() — typically when the memory manager could not acquire the requested page size and silently allocated less, or a caller passes a mis-sized array.
Common situations: Heavy memory pressure: executor heap fully consumed by cached blocks/pages so the allocator grants a smaller array; misconfigured memory fractions leaving too little execution memory for the sorter to double its pointer array.
Related errors
- There is no space for new record
- error while calling spill() on
- error while calling spill() on
- Unable to acquire bytes of memory, got
- Comparison method violates its general contract!
AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11).
Data as JSON: /api/errors/6c97e08b17625f76.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/io/mycat/memory/unsafe/utils/sort/UnsafeInMemorySorter.java:195
/**
* @return the total amount of time spent sorting data (in-memory only).
*/
public long getSortTimeNanos() {
return totalSortTimeNanos;
}
public long getMemoryUsage() {
return array.size() * 8;
}
public boolean hasSpaceForAnotherRecord() {
return pos + 1 < (array.size() / memoryAllocationFactor);
}
public void expandPointerArray(LongArray newArray) {
if (newArray.size() < array.size()) {
throw new OutOfMemoryError("Not enough memory to grow pointer array");
}
Platform.copyMemory(
array.getBaseObject(),
array.getBaseOffset(),
newArray.getBaseObject(),
newArray.getBaseOffset(),
array.size() * (8 / memoryAllocationFactor));
consumer.freeLongArray(array);
array = newArray;
}
/**
* Inserts a record to be sorted. Assumes that the record pointer points to a record length
* stored as a 4-byte integer, followed by the record's bytes.
*
* @param recordPointer pointer to a record in a data page, encoded by {@link DataNodeMemoryManager}.
* @param keyPrefix a user-defined key prefix
*/View on GitHub (pinned to 65f8d8beb7)