| |
| Posted by Eugene Wissner | PermalinkReply |
|
Eugene Wissner
| https://issues.dlang.org/show_bug.cgi?id=9614
Eugene Wissner <belka@caraus.de> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |belka@caraus.de
--- Comment #2 from Eugene Wissner <belka@caraus.de> ---
This problem affects dmd, with or without -m32, and ldc aswell.
When referencing memory via a variable on the stack, by the time the garbage collector runs, due to alignment and =voids the stack reference to the variable has not necessarily been overwritten. As a result, memory may be kept alive by garbage pointers.
Even calling the GC manually high up the stack does not necessarily solve this, as by the time the GC determines the stack pointer, it's already several stackframes down from usercode.
This is especially problematic if the pointer is to a heavily-crossreferenced data structure, such as an XML tree, where a single pointer anywhere into the tree may keep the whole thing alive.
The correct solution would be to find a way to make stack garbage collection type-aware; however, the mechanics of this heavily depend on the compiler backend.
A compiler-level workaround may be to add a flag to zero any gaps in the stack and initialize void variables to 0.
Alternatively, a user-level workaround may be to periodically wipe the stack somewhere early in the calltree.
import core.memory, std.stdio, core.thread;
void test() {
// Allocate some memory and store it on a variable on the stack.
auto array = new ubyte[128*1024*1024];
// The variable's lifetime ends here.
}
void purify() {
ubyte[0x1000] filler = void;
import core.stdc.string: memset;
// To ensure the compiler doesn't optimize out the unused variable, zero it
manually.
memset(filler.ptr, 0, 0x1000);
}
void main() {
writeln("Allocate 100MB");
auto before = GC.stats.usedSize;
test();
// purify();
GC.collect();
auto after = GC.stats.usedSize;
assert(after < before + 100*1024*1024, "GC failed to free the allocation!");
writeln("GC successfully freed allocated memory.");
}
--
|