ben-manes/caffeine · critical

Fail to alloc memory!\n

Error message

Fail to alloc memory!\n

What it means

This is a C runtime check in the bundled LIRS trace replay tool (lirs.c, used by the simulator's LIRS trace converter). At initialization it calloc's the evict_list array (EVICT_LIST_SIZE unsigned longs) that records the eviction sequence; if calloc returns NULL the process prints this message and exits with status 1. It means the process could not allocate the (small, fixed-size) eviction bookkeeping buffer, i.e. the heap is exhausted or the process hit an allocation limit.

Source

Thrown at simulator/src/main/resources/com/github/benmanes/caffeine/cache/simulator/parser/lirs/lirs.c:101

    page_tbl[i].LIRS_prev = NULL;

    page_tbl[i].HIR_rsd_next = NULL;
    page_tbl[i].HIR_rsd_prev = NULL;

    page_tbl[i].recency = S_STACK_OUT;
  }

  LRU_list_head = NULL;
  LRU_list_tail = NULL;

  HIR_list_head = NULL;
  HIR_list_tail = NULL;

  LIR_LRU_block_ptr = NULL;

  evict_list = (unsigned long *)calloc(EVICT_LIST_SIZE, sizeof(unsigned long));
  if (!evict_list) {
    fprintf(stderr, "Fail to alloc memory!\n");
    exit(1);
  }
  evict_max_idx = EVICT_LIST_SIZE;
  evict_cur_idx = 0;

  /* the memory ratio for hirs is 1% */
  HIR_block_portion_limit = (unsigned long)(HIR_RATE/100.0*mem_size);
  if (HIR_block_portion_limit < LOWEST_HG_NUM)
    HIR_block_portion_limit = LOWEST_HG_NUM;

  LIRS_Repl(trace_fp);

  printf("\n");
  printf(" Memory size                        = %ld\n", mem_size);
//  printf(" Llirs (record size for LIRS stack) = %ld\n", cur_lir_S_len);
  printf(" Lhirs (cache size for HIR blocks)  = %ld\n", HIR_block_portion_limit);
  printf(" Final blocks refs                  = %ld\n", total_pg_refs);
  printf(" Final number of misses             = %ld \n", num_pg_flt);

View on GitHub (pinned to 9da6581ee3)

Solutions

  1. Free memory or raise the container/ulimit limit and rerun the trace conversion
  2. Check with dmesg/top whether the host was OOM; if so, run on a machine with more RAM or process a smaller trace
  3. If self-compiling, verify EVICT_LIST_SIZE was not accidentally set huge by local modifications
Defensive patterns

Strategy: validation

Validate before calling

# before running the LIRS conversion, confirm headroom
required=$((EVICT_LIST_SIZE * 8))
avail=$(free -b | awk '/Mem:/{print $7}')
[ "$avail" -gt "$((required * 4))" ] || { echo "not enough memory"; exit 1; }

Prevention

When it happens

Trigger: Running the LIRS parser/replayer when the process has exhausted its address space or memory quota; ulimit -v restrictions; a tiny embedded/container environment with a hard memory cap; extremely constrained memory after the caller has already allocated the page tables.

Common situations: Docker/Kubernetes containers with low memory limits running the simulator trace conversion; CI jobs with ulimit -v set; 32-bit builds where address space runs out; OOM conditions on the host.

Related errors


AI-assisted analysis of ben-manes/caffeine@9da6581ee3 (2026-08-14). Data as JSON: /api/errors/3b46b5d595b89b6e. Report an issue: GitHub.