Thread overview
Tracking memory usage
Aug 07, 2016
Alfred Pincher
Aug 07, 2016
Basile B.
Aug 08, 2016
Cauterite
August 07, 2016
Hi, I have written some code that tracks all memory allocations and deallocations when using my own memory interface. It is non gc based.

It reports the results of each allocation when the memory balance for the pointer allocated is non-zero. It gives the stack trace of the allocations and deallocations if they exist long with statistics collected from the allocators and deallocators.

It is very handy but I rely on hacks to accomplish the task. Does D have any solution for handling non-gc and/or gc memory inspection? With my code, if I miss a free, it is reported, this is a very nice feature. I hope D has something similar?




August 07, 2016
On Sunday, 7 August 2016 at 00:28:40 UTC, Alfred Pincher wrote:
> Hi, I have written some code that tracks all memory allocations and deallocations when using my own memory interface. It is non gc based.
>
> It reports the results of each allocation when the memory balance for the pointer allocated is non-zero. It gives the stack trace of the allocations and deallocations if they exist long with statistics collected from the allocators and deallocators.
>
> It is very handy but I rely on hacks to accomplish the task. Does D have any solution for handling non-gc and/or gc memory inspection? With my code, if I miss a free, it is reported, this is a very nice feature. I hope D has something similar?

http://www.cprogramming.com/debugging/valgrind.html
August 08, 2016
On Sunday, 7 August 2016 at 00:28:40 UTC, Alfred Pincher wrote:
> this is a very nice feature. I hope D has something similar?

If you want to implement that kind of allocation tracking you'll probably want to use gc_getProxy()+gc_setProxy(). They're global C functions you can access by declaring:
extern(C) gc.gcinterface.GC gc_getProxy() nothrow;
extern(C) void gc_setProxy(gc.gcinterface.GC);

First call gc_getProxy() to get the real GC instance and save it somewhere.
Then call gc_setProxy() with your object implementing the GC interface functions, and in each function forward to the corresponding function of the real GC instance, after any statistic-gathering code you want run.

Something like this:

__gshared GC RealGcInstance = gc_getProxy();
__gshared GC MyProxy = new class GC {
	// ...
	extern(C) void gc_free(void* Ptr) nothrow {
		printf("freeing pointer %x\n", Ptr); // or whatever
		return RealGcInstance.free(Ptr);
	};
	// ... etc.
};
gc_setProxy(MyProxy);

I haven't tested this method myself, but it will probably work. Refer to https://github.com/dlang/druntime/blob/master/src/gc/proxy.d and https://github.com/dlang/druntime/blob/master/src/gc/gcinterface.d

Also remember that you can't invoke the GC from inside the proxy functions. Using helper functions marked @nogc might make it easier to avoid.