4 ms·
Possible, but probably not practical. It has certainly been done in various Java implementations. HotSpot I'm pretty sure does precise garbage collection. Nat
by ssp 16y ago
Possible, but probably not practical.
It has certainly been done in various Java implementations. HotSpot I'm pretty sure does precise garbage collection.
Native stacks don't need to be scanned for pointers, but the VM must of course keep track of which parts of the stack are native.
- barrkel 16y agoWhat you do is stop the world for a moment, set a GC due flag, and then wait for threads to come to GC-safe points. At GC safe points, the set of live registers and stack locations is definitely known.
- dfox 16y agoThis does not work when you can have threads executing arbitrary native code, that can do some non-GC related work for essentially unbounded time, which is certainly case with .NET. In JVM any native code tends to be prepared to cope with this somehow, but .NET is explicitly designed to be able to seamlessly interoperate with random COM and legacy native libraries, so you cannot guarantee that such native code will get back to GC safe point in any bounded amount of time. Edit: you can do stop-the-world GC at any point of program whan you scan stack conservatively, GC-safe points are only needed for precise scanning of stack and registers, so this is problem only when you want to be fully precise. Fully precise GC is certainly better when it is possible, but conservative scan works mostly well enough.
- barrkel 16y agoArbitrary native code is just fine - all you need to do is catch it when it returns back into the CLR. Native code can't (legally) have access to any managed memory that isn't already pinned. Since you (by you, I mean the CLR) control the call point to native code, you control the return point too - you can patch the instructions after the call if necessary.
- thedigitalengel 16y agoWhat happens if the native code enters, say, an infinite loop?
- ssp 16y agoYou can just consider native code a GC point. When executing native code, the registers don't need to be scanned, and you can keep track of what parts of the stack are native by noting the state of the stack before entering the native code.
- thedigitalengel 16y agoEven with the threads possibly stopping at unsafe points, a mostly precise scan (saving the last stack frame) can be done if the stack maps are maintained for all the call-sites.
- thedigitalengel 16y agoThat imposes an uncalled for runtime overhead. A better way would be to implement it using code-patching, by overwriting the instructions at specific pre-determined locations which will then cause the thread to halt when executed.
- dfox 16y agoHotSpot uses very different method for interfacing with native code, thus this problem is partially mitigated. However only small part of heap is directly referenced by stack/registers so you can get away with simpler conservative implementation. Many Smalltalk and CL implementations scan stack and registers conservatively (for example SBCL and ST/X).
- ssp 16y agoHowever only small part of heap is directly referenced by stack/registers But those few objects referenced directly may keep a lot of other stuff alive. It's not that uncommon to have left-over pointers on the stack that are no longer live, but still reference a large graph of objects.