Skip to content
Back to the collection

Low-latency, high-throughput garbage collection

Wenyu Zhao, Stephen M. Blackburn, Kathryn S. McKinley

2022 · Proceedings of the 43rd ACM SIGPLAN International Conference on Programming Language Design and Implementation

Read the paper
HN score
0
Mentions
4
Readers
3
Months
3
What’s in a score?

In the conversation

Original HN comments, with labels from simple text rules. A label describes the whole comment and may miss context or irony. Read the discussion to make up your own mind. About the labels

4 selected excerpts · 4 total mentions

densh
Neutral mention · rule
Hey, as someone who spent a few years reimplementing another language trying to decouple it from JVM (Scala JVM -> Scala Native), some pitfalls to avoid: - Don't try to provide backwards compatible subset of JVM APIs. While this might seem tempting to support very important library X with just a bit of work, I'd rather see new APIs that are only possible with your language / runtime. Otherwise you might end up stuck in never-ending stream of requests to add one more JVM feature to get yet another library from the original JVM language running. Focus on providing your own unique APIs or bindings to native projects that might not be easy to do elsewhere. - Don't implement…
Read the full comment
your own GC, just use mmtk [1]. It takes a really long time to implement something competitive, and mmtk already has an extensible and pluggable GC design that gets some of the best performance available today [2] without much effort on your end. - Don't underestimate complexity and importance of multi-threading and concurrency. Try to think of supporting some form of it early or you might get stuck single threaded world forever (see CPython). Maybe you don't do shared memory multi threading and then it could be quite easy to implement (as in erlang). No shared memory also means no shared heap, which makes GCs's life much easier. - Don't spend too much time benchmarking and optimizing single threaded performance against JVM as performance baseline. If you don't have a compelling use case (usually due to unique libraries), the performance might not matter enough for users to migrate to your language. When you do optimize, I'd rather see fast startup, interactive environment (think V8), over slow startup but eventually efficient after super long warmup (like jvm). I see that jank is already doing at least some of the things right based on the docs, so this message might be more of a dump of mistakes I've done previously in this space. [1]: https://github.com/mmtk/mmtk-core [2]: https://dl.acm.org/doi/pdf/10.1145/3519939.3523440
carry_bit
Neutral mention · rule
The state-of-the-art in refcounting[1] greatly improves the barrier situation over a naïve implementation: no read barrier, and the write barrier only uses atomics when mutating an (apparently) unmodified field in an old generation object. [1] https://dl.acm.org/doi/pdf/10.1145/3519939.3523440
adgjlsfhk1
Neutral mention · rule
Four reasons: 1. Reference counting scales with number of dead objects while Mark+Sweep typically scales with number of alive objects. This means that if you collect infrequently enough, a GC will have strictly less work to do. 2. RC involves a write whenever the reference count is increased. This means that in multi threaded contexts you need an atomic whenever a new reference is added. This will absolutely destroy performance in multi-threaded apps (this is the main reason why multi-threading in python doesn't exist). 3. RC requires a fairly high amount of metadata (often 32-64 bits per object). Mark sweep on the other hand often only needs a few (e.g. 2) bits per object. This is pretty heavy, especially for languages where everything is an object. 4. Circular references That said there is recent research suggesting that good algorithms can be made by combining RC with mark-sweep (e.g. https://dl.acm.org/doi/10.1145/3519939.3523440)

Keep following the thread.

More in Other research

More from the same topics.