{"record":{"id":"272b27b333c0feca","repo":"nodejs/node","slug":"u-memory-allocation-error-272b27","errorCode":"U_MEMORY_ALLOCATION_ERROR","errorMessage":"error: %s - out of memory\n","messagePattern":"error: (.+?) - out of memory\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"deps/icu-small/source/tools/toolutil/toolutil.cpp","lineNumber":353,"sourceCode":"\nstruct UToolMemory {\n    char name[64];\n    int32_t capacity, maxCapacity, size, idx;\n    void *array;\n    alignas(std::max_align_t) char staticArray[1];\n};\n\nU_CAPI UToolMemory * U_EXPORT2\nutm_open(const char *name, int32_t initialCapacity, int32_t maxCapacity, int32_t size) {\n    UToolMemory *mem;\n\n    if(maxCapacity<initialCapacity) {\n        maxCapacity=initialCapacity;\n    }\n\n    mem=(UToolMemory *)uprv_malloc(sizeof(UToolMemory)+initialCapacity*size);\n    if(mem==nullptr) {\n        fprintf(stderr, \"error: %s - out of memory\\n\", name);\n        exit(U_MEMORY_ALLOCATION_ERROR);\n    }\n    mem->array=mem->staticArray;\n\n    uprv_strcpy(mem->name, name);\n    mem->capacity=initialCapacity;\n    mem->maxCapacity=maxCapacity;\n    mem->size=size;\n    mem->idx=0;\n    return mem;\n}\n\nU_CAPI void U_EXPORT2\nutm_close(UToolMemory *mem) {\n    if(mem!=nullptr) {\n        if(mem->array!=mem->staticArray) {\n            uprv_free(mem->array);\n        }","sourceCodeStart":335,"sourceCodeEnd":371,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/deps/icu-small/source/tools/toolutil/toolutil.cpp#L335-L371","documentation":"Fatal out-of-memory error in utm_open() — the UToolMemory allocation function. When uprv_malloc fails to allocate the initial UToolMemory struct plus the static array (sizeof(UToolMemory) + initialCapacity * size bytes), the tool prints the error with the memory block's name and exits with U_MEMORY_ALLOCATION_ERROR. This is an unrecoverable condition — the process terminates immediately.","triggerScenarios":"utm_open() is called with a large initialCapacity * size product that exceeds available memory, or the system is under severe memory pressure. The uprv_malloc returns nullptr, triggering exit(U_MEMORY_ALLOCATION_ERROR). Used throughout ICU data generation tools for dynamic array management.","commonSituations":"Building ICU data on systems with insufficient RAM; requesting an excessively large initial capacity; memory leaks in long-running build processes depleting available memory; 32-bit process address space limits.","solutions":["Reduce the initialCapacity parameter passed to utm_open() if it is unreasonably large.","Free other memory allocations before calling utm_open() to reduce overall memory pressure.","Build on a system with more available RAM or swap space.","If on a 32-bit system, switch to a 64-bit build to remove address space limits.","Check for memory leaks in the build tool using Valgrind or AddressSanitizer."],"exampleFix":"// before\nUToolMemory *mem = utm_open(\"bigdata\", 10000000, 10000000, sizeof(int32_t));\n// after — smaller initial capacity with growth\nUToolMemory *mem = utm_open(\"bigdata\", 1024, 10000000, sizeof(int32_t));","handlingStrategy":"validation","validationCode":"// Pre-check available memory before utm_open (heuristic)\n#include <sys/resource.h>\n#include <unistd.h>\n\nbool canAllocate(size_t bytes) {\n#ifdef _SC_AVPHYS_PAGES\n    long pages = sysconf(_SC_AVPHYS_PAGES);\n    long pageSize = sysconf(_SC_PAGE_SIZE);\n    if (pages > 0 && pageSize > 0) {\n        size_t avail = (size_t)pages * (size_t)pageSize;\n        return (avail > bytes * 2); // 2x safety margin\n    }\n#endif\n    return true; // Cannot determine; proceed optimistically\n}\n\nbool safeUtmOpen(size_t initialCapacity, int32_t size) {\n    size_t needed = sizeof(UToolMemory) + initialCapacity * size;\n    return canAllocate(needed);\n}","typeGuard":null,"tryCatchPattern":"// utm_open calls exit() on failure — there is no try-catch recovery.\n// To guard, check memory availability before calling:\nif (!canAllocate(sizeof(UToolMemory) + (size_t)initCap * elemSize)) {\n    fprintf(stderr, \"Insufficient memory for utm_open; aborting gracefully\\n\");\n    return EXIT_FAILURE;\n}\nUToolMemory* mem = utm_open(name, initCap, maxCap, elemSize);","preventionTips":["Use conservative initialCapacity values — utm grows dynamically.","Monitor available memory before large allocations in build tools.","Build on systems with adequate RAM for the data being generated.","Use 64-bit builds to avoid address space limits.","Run memory-intensive builds with adequate swap configured."],"tags":["icu","memory","out-of-memory","fatal-exit","build-tool"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}