Skip to content

Instantly share code, notes, and snippets.

@rodesai
Created October 6, 2020 06:44
Show Gist options
  • Save rodesai/725255bfb871b34b1dff3e9eaeec7a00 to your computer and use it in GitHub Desktop.
Save rodesai/725255bfb871b34b1dff3e9eaeec7a00 to your computer and use it in GitHub Desktop.
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