Skip to content
HomeVideosBooksBlogs
AllTop postsTopics
Podcasts
HistoryListsWatch laterLiked videosFollowing

The videos, books, blogs and podcasts Hacker News keeps recommending, all in one place.

VideosBooksBlogsPodcastsAboutPrivacySettings

Data from Hacker News, HackerTube, HackerBooks, HackerBlogs and Open Library. Credits · Not affiliated with Y Combinator.

HomeVideosBooksBlogsPodcasts
Ctrl K
    F

    Felix Klock

    blog.pnkfx.org · Personal blog · on HN since 2015

    Felix Klock, a Rust compiler team member, writes about garbage collection in Rust, non-lexical lifetimes, linking and debugging.

    Visit blogHN submissions
    Languages & CompilersSystems & Performance
    What HN says

    HN commenters cite his posts to explain how Rust's static memory management conflicts with GC and to frame memory safety in terms of blame.

    Stats for nerds
    16HN people shared it
    13linked in comments
    388story points
    Mar 2023last shared
    2016people per year2023

    Top posts on HN

    1. 1
      GC and Rust Part 1: Specifying the Problem
      4 people · 142 points · first shared 2015 · 23 comments on HN
    2. 2
      Rust Bug Minimization Patterns
      1 person · 90 points · first shared 2019 · 12 comments on HN
    3. 3
      What Is Rust's Hole Purpose?
      2 people · 65 points · first shared 2022 · 159 comments on HN
    4. 4
      Non-Lexical Lifetimes in Rust Arrives for Everyone
      2 people · 53 points · first shared 2019 · 2 comments on HN
    5. 5
      Why I use a debugger
      3 people · 31 points · first shared 2022 · 77 comments on HN
    6. 6
      Linking Rust Crates, Part 1
      2 people · 4 points · first shared 2022 · Discussion on HN
    7. 7
      GC and Rust Part 2: The Roots of the Problem
      4 people · 3 points · first shared 2016 · Discussion on HN
    8. 8
      Gc and rust part 0 how does gc work
      1 person · first shared 2016
    9. 9
      Gc
      1 person · first shared 2020

    What HN people wrote when they linked it

    • chubotMar 2023

      The way I would frame this is that Rust has static (compile-time) memory management, and that conflicts with dynamic memory management (garbage collection).

      The boundary is awkward and creates complexity.

      I wrote a post about problems writing a garbage collector in C++, e.g. annotating the root set, and having precise metadata for tracing.

      http://www.oilshell.org/blog/2023/01/garbage-collector.html

      https://news.ycombinator.com/item?id=34350260

      I linked to this 2016 post about Rust, which makes me think the problem could be worse in Rust, although I haven't tried it:

      http://blog.pnkfx.org/blog/2016/01/01/gc-and-rust-part-2-roots-of-the-problem/

      I didn't write as much about bindings to native C++ code, but that's also an issue that you have to think about carefully. CPython has kind of been "stuck" with their API for decades, which exposes reference counting. So it's extraordinarily difficult to move to tracing GC, let alone moving GC, etc.

      ---

      On the other hand, there was also a paper that said Rust can be good for writing GCs.

      Rust as a Language for High Performance GC Implementation

      https://dl.acm.org/doi/pdf/10.1145/2926697.2926707

      However, I'm not sure it addresses the interface issue. One lesson I learned is that GCs are NOT modular pieces of code -- they have "tentacles" that touch the entire program!

      That said, C++ is pretty good at "typed memory" as well, and I think it's more pleasant than C. That is, you get more than void* and macros. So I can…

    • RuskyMay 2020

      That's an interesting question, and there has been some work in that area.

      Getting shared mutability as a user of GC is basically the same as getting shared mutability in any other scenario in Rust. You use `UnsafeCell<T>` or a safe wrapper around it, like `Mutex` or `Cell`. You can get a feel for this even in idiomatic Rust using `Rc` instead of a tracing GC.

      When you start looking at other methods of GC things get trickier. Even with `UnsafeCell<T>` the GC can't, in general, know whether something is borrowed (mutably or immutably) by the mutator, so the problem to be solved is finding ways to enforce that there are no references into the heap at all, when collection needs to happen.

      But when you think about it, this is actually not so different from the usual problem of GC safepoints. The problem is the same- enforce that there are no un-rooted pointers into the heap, when collection needs to happen.

      And it turns out there are some tricks you can do with lifetimes to get borrowck to enforce safepoints for you, and it could even be made pretty ergonomic in the future.

      Some early discussion of the problem space:

      * http://blog.pnkfx.org/blog/categories/gc/

      * https://manishearth.github.io/blog/2015/09/01/designing-a-gc-in-rust/

      * https://manishearth.github.io/blog/2016/08/18/gc-support-in-rust-api-design/

      A design from Servo, and a paper to go with it: https://github.com/asajeffrey/josephine

      A series of blogposts describing a more recent attempt:…

    • dimfeldJan 2016

      It's both faster and you have more control over it; the two are linked in this case. This system lets the compiler do the hard work to figure out when it's ok to deallocate some piece of memory, unlike a GC, which figures it out at runtime. One you've determined that some memory can be deallocated, the actual process is very quick, usually just updating a list of free blocks in the memory allocator and maybe some statistics.

      Rust does also support reference counting when you want it, which can bring its own set of performance issues in certain circumstances. Think more about general slowness due to constantly incrementing and decrementing references in an atomic fashion when you pass RC-ed data between functions, rather than the pauses seen with garbage collection. But how bad that is depends greatly on how and where you're using reference counted variables, and the addition of the lifetime/borrow system makes it easier to avoid some of the more egregious cases here.

      Additionally, some people are doing work on GCs that work with Rust. The two links below have some good descriptions of the progress and challenges related to that.

      http://blog.pnkfx.org/blog/2015/10/27/gc-and-rust-part-0-how-does-gc-work/
      http://manishearth.github.io/blog/2015/09/01/designing-a-gc-in-rust/

    • bjz_Jan 2016

      pnkfelix (from Mozilla) has been doing lots of investigation into custom allocators[0], custom GCs, and embedding Rust into places where a GC is already active. He also recently published some blog posts outlining the problem of GC interop[1][2]. Quoting aturon[3]:

      > To be clear, a major goal of this project -- outlined in the earlier blog posts -- is "GC as Interoperation Feature". That is, we want to embed Rust code into contexts with existing GCs (such as the V8 or SpiderMonkey Javascript engines), and so Felix is trying to find ways to accommodate a relatively wide range of GC approaches, with maximally safe, efficient, and ergonomic support on the Rust side.

      Might be a while off before good support for custom GCs for pure Rust code, but it's definitely being thought about.

      [0]: https://github.com/rust-lang/rfcs/pull/1398

      [1]: http://blog.pnkfx.org/blog/2015/11/10/gc-and-rust-part-1-specing-the-problem/

      [2]: http://blog.pnkfx.org/blog/2016/01/01/gc-and-rust-part-2-roots-of-the-problem/

      [3]: https://www.reddit.com/r/rust/comments/3zqtoc/gc_and_rust_part_2_the_roots_of_the_problem/cyp0gfu

    • mastaxSep 2016

      > Given that Rust was designed by a group known for writing web browsers, how does that work out in practice, given that the DOM is a deep bidirectional graph?

      I believe that the JS engine has ownership over the DOM, and pointers into the DOM are GC'd by the JS engine. This is part of the motivation for adding hooks for GC's in Rust. These posts [1][2] discusses this, although I think there is a more recent one. Edit: more recent one here [4].

      > Now, I'm not sure how you would encode this into a compiler, so the discussion may have to end there as being impractical to implement.

      This seems like a good use case for a Weak<> pointer [3].

      [1]: http://blog.pnkfx.org/blog/2015/11/10/gc-and-rust-part-1-specing-the-problem/
      [2]: http://blog.pnkfx.org/blog/2016/01/01/gc-and-rust-part-2-roots-of-the-problem/
      [3]: https://doc.rust-lang.org/std/rc/struct.Weak.html
      [4]: http://manishearth.github.io/blog/2016/08/18/gc-support-in-rust-api-design/

    • pcwaltonFeb 2022

      This is why it's more useful to talk about blame: http://blog.pnkfx.org/blog/2022/02/09/what-is-rusts-hole-purpose/

      Regarding memory safety, C++ says: "It's your fault if you get it wrong." Rust says: "It's our fault if we get it wrong in safe code." There is an enormous qualitative difference (in terms of ease of programming) and quantitative difference (in terms of number of bugs) between the two.

    Related

    Manish Goregaokarmanishearth.github.io97 people

    Picking Apart the Crashing iOS String

    Manish Goregaokar
    Personal · last shared 2026
    Philipp Oppermannos.phil-opp.com95 people

    Learn Rust by writing a small OS

    Philipp Oppermann
    Personal · last shared 2026
    Brian Andersonbrson.github.io32 people

    Dave Herman’s contributions to Rust

    Brian Anderson
    Personal · last shared 2025
    Rust Blogblog.rust-lang.org533 people

    Announcing Rust 1.0

    Rust Blog
    Company · last shared 2026
    Niko Matsakissmallcultfollowing.com221 people

    Towards a Rust Foundation

    Niko Matsakis
    Personal · last shared 2026
    Ralf Jungralfj.de99 people

    There is no memory safety without thread safety

    Ralf Jung
    Personal · last shared 2026
    Mechanical Sympathymechanical-sympathy.blogspot.com79 people

    Memory Access Patterns Are Important (2012)

    Mechanical Sympathy
    Personal · last shared 2026
    without.boatswithout.boats80 people

    Pin

    without.boats
    Personal · last shared 2026