Re:Rust means never having to close a socket
by chaotic-good on Wednesday October 08, 2014 @07:46AM
(#8426381)
Good generational GC doesn't need to deallocate objects one by one, instead of that it can deallocate objects in bulk (if there is no finalizers). It can allocate memory faster because it doesn't need to use memory allocator to create every object, it just increment pointer that points to the beginning of the free space. It's true that modern GC has greater throughput than simple allocation/deallocation schemes. Problem is predictability (as been mentioned).
Re:Rust means never having to close a socket
by spullara on Tuesday October 07, 2014 @04:01PM
(#8423650)
It doesn't have to deallocate dead objects. That is sort of the point of most collectors.
Re:Rust means never having to close a socket
by pcwalton on Tuesday October 07, 2014 @05:28PM
(#8424124)
All GCs have to deallocate objects. It may be very cheap to do so, for example when you have a semispace collector and no finalizers, but switching the spaces is still a form of deallocation. Production-quality GCs don't use semispace for everything because of the huge memory use overhead, and all practical GC'd languages I know of need finalizers in some form.
Re:Rust means never having to close a socket
by spullara on Tuesday October 07, 2014 @07:20PM
(#8424539)
Finalizers are certainly the exception rather than the rule for objects. Deallocation to me represents some action taken for a particular object and scales with the number of objects deallocated. Semi-space copying collectors do not have this property. I think we only disagree on the semantics of "deallocation" — which is why I specified my argument in terms of how things scale. Similarly compacting collectors like Java's CMS also have this scaling property without semi-spaces.
Re:Rust means never having to close a socket
by silon5 on Wednesday October 08, 2014 @08:06AM
(#8426440)
But it has to scan/mark all the objects, not just the the unused ones. This has large overhead in big-mem apps. Not to mention that usually this forces the whole app into RAM (makes swap useless) and also potentialy drains cpu caches.
And to amortize this it often has more memory overhead (up to 2x) than typical fragmentation in a manually managed app.
A GC has to determine liveness of objects, so it has to traverse the object graph (or at least the most recent generation if the GC is generational) to know which objects are still alive and which aren't. That's what "GC scaling" refers to. Then it still has to deallocate dead objects, and pay the same deallocation cost as scope-bound free.