Skip to content

Instantly share code, notes, and snippets.

@wjlroe
Last active March 25, 2024 12:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wjlroe/aa13050a34eb49f267f11de00aced935 to your computer and use it in GitHub Desktop.
Save wjlroe/aa13050a34eb49f267f11de00aced935 to your computer and use it in GitHub Desktop.
Can you detect memory allocated via malloc in C (via Ruby's FFI) when calling GC.stat?

Results of running this:

❯ ruby ffi.rb
Allocating 1048576 via malloc in FFI
	before malloc: 		maxrss: 	37044224
	before scribble: 	maxrss: 	37093376
	after scribble: 	maxrss: 	38141952
heap_live_slots: 48069 -> 48073 (diff: 4)
heap_free_slots: 4098 -> 4094 (diff: -4)
total_allocated_objects: 151713 -> 151717 (diff: 4)
malloc_increase_bytes: 659264 -> 660640 (diff: 1376)
oldmalloc_increase_bytes: 659264 -> 660640 (diff: 1376)


Allocating 1073741824 via malloc in FFI
	before malloc: 		maxrss: 	38141952
	before scribble: 	maxrss: 	38141952
	after scribble: 	maxrss: 	1111883776
heap_live_slots: 48103 -> 48104 (diff: 1)
heap_free_slots: 4064 -> 4063 (diff: -1)
total_allocated_objects: 151747 -> 151748 (diff: 1)
malloc_increase_bytes: 661840 -> 662736 (diff: 896)
oldmalloc_increase_bytes: 661840 -> 662736 (diff: 896)
require 'ffi'
module MyLib
extend FFI::Library
ffi_lib './my_ffi.o'
attach_function :consume_many_memories, [:int], :void
end
def report_mem(size)
puts "Allocating #{size} via malloc in FFI"
before = GC.stat
MyLib.consume_many_memories(size)
after = GC.stat
before.each_key do |key|
before_val = before.fetch(key)
after_val = after.fetch(key)
if after_val != before_val
puts "#{key}: #{before_val} -> #{after_val} (diff: #{after_val - before_val})"
end
end
end
report_mem(1024*1024)
puts
puts
report_mem(1024*1024*1024)
// Build with: cc -dynamiclib -o my_ffi.o my_ffi.c
#include "my_ffi.h"
static uint8_t *mem;
void report_mem_usage() {
struct rusage r_usage;
getrusage(RUSAGE_SELF, &r_usage);
printf("\tmaxrss: \t %ld", r_usage.ru_maxrss);
}
void consume_many_memories(uint32_t size) {
printf("\tbefore malloc: \t");
report_mem_usage();
printf("\n");
mem = (uint8_t*)(malloc(size));
// scribble into the allocated memory to force a 'real' allocation
printf("\tbefore scribble: ");
report_mem_usage();
printf("\n");
for (uint32_t i = 0; i < size; i++) {
*mem = 1;
mem++;
}
printf("\tafter scribble: ");
report_mem_usage();
printf("\n");
}
#ifndef _MYLIB_H_
#define _MYLIB_H_
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/resource.h>
extern void consume_many_memories(uint32_t);
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment