6 ms·
> We also paid close attention to proper memory management, producing as little garbage as possible. The key. And I was wondering how can a tracing GC outperf
by habibur 4y ago
> We also paid close attention to proper memory management, producing as little garbage as possible.
The key.
And I was wondering how can a tracing GC outperform a non-tracing-GC memory manager.
- forrestthewoods 4y agoThe key to garbage collection is… to go super far out of your way to avoid allocating memory. This is not ideal.
- girvo 4y agoI'm probably biased because I live in firmware development these days, but that's true even for non-garbage collected languages when it comes to making sure things are fast
- ekidd 4y agoSpeaking as someone who has spent time optimizing C++ and Rust, memory allocation in hot loops is often where performance goes to die. GC or not, if you want to fast, reducing allocation is one of the first things to benchmark. (One fast way to manage allocations is to use an arena allocator that allocates memory by incrementing a pointer, and frees memory all at once. This is pretty effective for simple, short-lived requests.)
- forrestthewoods 4y agoYes, minimize malloc in all cases. The difference is that GC languages are fundamentally designed around the concept that it’s cheap and easy to malloc/free. Avoiding allocations can be excruciatingly difficult. In C++ you also need to minimize allocations, but it’s radically easier to do in C++ than in C#.
- throwaway81523 4y ago> And I was wondering how can a tracing GC outperform a non-tracing GC memory manager. The cliché is that malloc/free style memory management has to touch all the garbage in order to free it, while a semispace GC only has to copy the live data once in a while. The garbage is ignored.
- masklinn 4y agoAfaik Go uses a non-moving GC, so it can’t be a semi space.
- pkolaczk 4y agoHowever, when a tracing GC runs, it has to touch massive amounts of cold data and pushes hot data out of cache. Traditional malloc/free touches data in small chunks and freeing happens close to the last use, so when most of the data is still hot in cache. Stable, predictable performance is often more important than the peak performance.
- chrisseaton 4y agoManual memory management means your memory management is tightly interleaved with application code, with both competing for the same limited cache space. A tracing GC batches memory management, using cache better and not as frequently evicting your application’s data out of cache. A GC can also let you use more efficient concurrent data structures - many sophisticated concurrent objects require a tracing GC for implementing correctly - which can improve the performance of your application code.
- tialaramex 4y ago> many sophisticated concurrent objects require a tracing GC for implementing correctly What sort of "sophisticated concurrent objects" are you thinking of?
- chrisseaton 4y agoImplementing many lock-free data structures without a GC is still a research topic, for example requiring conversion to use epoch allocation.
- tialaramex 4y agoThis still seems very vague, I was looking for concrete examples where quite different arrangements like hazard pointers are for some reason impossible.
- chrisseaton 4y agoHazard pointers, epoch reclamation yeah are both examples of tools to work around the lack of GC, but they require new work to figure out how to apply them and they harm your throughput which is probably why you wanted these data structures in the first place. https://medium.com/@tylerneely/fear-and-loathing-in-lock-free-programming-7158b1cdd50c https://medium.com/@tylerneely/fear-and-loathing-in-lock-fre...
- yencabulator 4y ago