reproduce-memory-growth.c
#include <pthread.h> | |
#include <unistd.h> | |
#include <stdio.h> | |
#include <stdint.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <malloc.h> | |
#define SIZE 32 * 1024 | |
#define CACHE_SIZE 196608 | |
char *buffers[CACHE_SIZE]; | |
void * run_warm(void *arg) { | |
while (1) { | |
char *bufs[32]; | |
for (int i = 0; i < 32; i++) { | |
bufs[i] = malloc(43482); | |
} | |
sleep(5); | |
for (int i = 0; i< 32; i++) { | |
free(bufs[i]); | |
} | |
} | |
} | |
void * run_iteration(void * arg) { | |
uint64_t i = 0; | |
int64_t total_allocated = 0; | |
int64_t subheap_alloc = 0; | |
while (total_allocated < 100ULL * 1024 * 1024 * 1024) { | |
int64_t sz = SIZE + (64 - i % 128); | |
i++; | |
total_allocated += sz; | |
subheap_alloc += sz; | |
if (buffers[i % CACHE_SIZE]) { | |
free(buffers[i % CACHE_SIZE]); | |
} | |
buffers[i % CACHE_SIZE] = malloc(sz); | |
memset(buffers[i % CACHE_SIZE], i % 256, sz); | |
// every 60 MB or so (just under the observed heap size) leave a little unfreed blob | |
// so that the heap can't be shrunk | |
if (subheap_alloc > 60 * 1024 * 1024) { | |
void *blob = malloc(520); | |
memset(blob, 123, 520); | |
} | |
} | |
malloc_info(0, stdout); | |
return NULL; | |
} | |
int main (int argc, char **argv) { | |
// warmup to create 32 arenas | |
pthread_t tids[32]; | |
for (int i = 0; i < 32; i++) { | |
pthread_create(&tids[i], NULL, run_warm, NULL); | |
} | |
sleep(3); | |
malloc_info(0, stdout); | |
memset(buffers, 0, CACHE_SIZE * sizeof(char *)); | |
for (int i = 0; i < 3; i++) { | |
printf("Run iteration %d\n", i); | |
pthread_t tid; | |
pthread_create(&tid, NULL, run_iteration, NULL); | |
pthread_join(tid, NULL); | |
} | |
char key[1]; | |
puts("Press any key to exit..."); | |
fgets(key,1,stdin); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment