3 ms·
> MO the big GC related issue is lack of determinism especially in the management of external resources. This isn't a property of GCs per se; it's just that mo
by weberc2 8y ago
> MO the big GC related issue is lack of determinism especially in the management of external resources.
This isn't a property of GCs per se; it's just that most GCs are optimized for throughput. Go's GC's pause times are on the order of 1ms, which might not be appropriate for every application, but it's probably fine for soft-realtime systems. There are a lot of other levers one could imagine as well, like semantics for demarcating critical sections.
- arcticbull 8y agoLack of determinism is absolutely a property of GCs, by definition. You’re never 100% sure when a resource is going to get deallocated/finalized with absolute certainty. This is a dealbreaker for kernel type applications. For instance think of a network socket wrapped in a structure, you can’t rely on a finalizer invocation to close your file descriptor, you don’t know when if ever it will happen so you have to wrap it with your own brand of ref counting. I’m not criticizing pause times, but rather that you can’t rely on code inspection to identify the point of resource deallocation, which is pretty much the flagship feature of a GC :)
- jonathanstrange 8y agoWhy should the GC not be able to inform the programmer/language designer when memory is discarded? This is a non-issue. Besides, a kernel has to deal with plenty of forms of nondeterminism anyway.
- arcticbull 8y agoHow would the GC in this case inform you when an object is deallocated? The whole point is scope can be extended arbitrarily by anything and that finalization may happen, or it may not, at some point in the future.
- jonathanstrange 8y agoIn the same way as a kernel deals with e.g. with the question whether an I/O interaction has succeeded or failed? But there is a difference, a GC can guarantee that finalization will happen in the future, unless someone switches off the machine by pressing the power button. I/O cannot make this guarantee. Do you maybe have hard real-time systems in mind when you say "deterministic"? I agree that a GC would be a bad idea for those, but these require validation of the hardware in combination with the software anyway.
- arcticbull 8y agoNo GC I've ever encountered can guarantee a given object will be collected or finalized.
- rwmj 8y agoSorry but this is nonsense. There's a whole field of study of hard realtime garbage collection, and several implementations. Also it's easy even in ordinary GCs to determine when a resource will be freed in the cases when you need that, eg by providing a socket.close() method.
- arcticbull 8y agoI think we probably agree. I'm not arguing that you can't have hard realtime constraints on a GC language, just that when you're interfacing GC memory with underlying resources you have to graft your own ownership model on top (socket.close()) which is not enforced by the compiler (in any language I've seen) introducing a new vector for error. Rust binds the two deterministically and statically validates both.
- weberc2 8y ago> I’m not criticizing pause times, but rather that you can’t rely on code inspection to identify the point of resource deallocation, which is pretty much the flagship feature of a GC :) This is completely wrong. The flagship feature of a GC is memory management, __not__ filehandle management or management of other resources. While many GCs support finalizer hooks, most languages with GCs (Go, Python, etc) explicitly discourage using these to close file handles for specifically the reasons you cite. Automatic resource management is useful and desirable, but it's out of scope for GCs.
- arcticbull 8y agoIn re-reading my statement, I understand the confusion, when I said 'not being able to rely on code inspection is the flagship feature of a GC' I meant, glibly, that non-deterministic deallocation of memory in a way the programmer does not have to (alternatively, cannot) reason about meaningfully. I suppose in reality it depends. Finalizer hooks are absolutely bad, I agree. Which means that resource management has to be grafted on top of a GC memory model. Since the compiler won't be helping you enforce the management of resources since, as you point out, it's out of scope, it introduces a new vector for error. Rust allows you to bind the two and handle them together, both in a checked/enforced way. I've yet to see a GC'd language that does the same, but I can't think of why one couldn't exist.
- weberc2 8y ago> Since the compiler won't be helping you enforce the management of resources since, as you point out, it's out of scope, it introduces a new vector for error It's not a new vector of error; it's the same vector that C has to deal with. > resource management has to be grafted on top of a GC memory model Only if this means "don't bind resource lifetimes to memory lifetimes", which is the solution that every tracing GC language implementation (that I'm aware of) uses. There's nothing stopping you from refcounting file handles just like you would in C. The compiler could even automatically add in the refcounting instructions for you, or the language runtime could have a special GC just for file handles.
- 8y ago