[HN Gopher] Untangling Lifetimes: The Arena Allocator
       ___________________________________________________________________
        
       Untangling Lifetimes: The Arena Allocator
        
       Author : signa11
       Score  : 40 points
       Date   : 2025-06-28 08:45 UTC (14 hours ago)
        
 (HTM) web link (www.rfleury.com)
 (TXT) w3m dump (www.rfleury.com)
        
       | williamcotton wrote:
       | Another use case is a per-request arena for a web server.
        
         | nine_k wrote:
         | If PHP did _one_ thing right, it is this: allocate resources
         | while handling a request, free them all unconditionally when
         | the response has been sent.
        
       | gorjusborg wrote:
       | It seems like the choice of a stacklike Arena API makes the
       | examples a little more confusing than needed. An arena doesn't
       | necessarily mean allocation 2 must be freed before allocation 1.
       | 
       | If this seems cool to you, check out Zig. The libraries use a
       | similar convention where code that might allocate requires
       | passing an allocator, which may be an arena, or something cool we
       | don't even know about yet.
        
       | ykonstant wrote:
       | The author's defense of C reminds me of this classic youtube
       | video:
       | https://www.youtube.com/watch?v=443UNeGrFoM&pp=ygUPaG93IGkgc...
       | 
       | I am sure the video above will cause immediate disagreement (I
       | think it goes too far on some topics), but I urge people to
       | consider the ideas contained within.
       | 
       | (I seem to have mis-posted this to another thread?)
        
       | nine_k wrote:
       | This article is quite long, and spends many kilobytes to make the
       | following points (AFAICT):
       | 
       | - Pure malloc/free allocation is error-prone and expensive; it's
       | too granular in many cases.
       | 
       | - Stack allocation has obvious limitations due to its LIFO
       | nature. RAII has similar limitations.
       | 
       | - Let's use a bunch o separate, independent allocators / memory
       | arenas instead. We can free them more quickly in one go when
       | needed. We can group objects by lifetime using them. Having
       | thread-local arenas naturally separates thread-local allocations
       | from program-global allocations.
       | 
       | This sounds pretty reasonable, and, AFAIK, Zig leans heavily on
       | this concept. I wonder if Rust can reap some of the benefits of
       | arena-based allocation by leveraging its lifetime tracking.
        
         | SeanAnderson wrote:
         | > I wonder if Rust can reap some of the benefits of arena-based
         | allocation by leveraging its lifetime tracking.
         | 
         | I'm reminded of one positive remark made here:
         | https://loglog.games/blog/leaving-rust-gamedev/#ecs-solves-t...
         | 
         | > The key point being, this allows a language like Rust to
         | completely side-step the borrow checker and allow us to do
         | "manual memory management with arenas" without actually
         | touching any hairy pointers, and while remaining 100% safe. If
         | there was one thing to point at that I like about Rust, it'd be
         | this. Especially with a library like thunderdome it really
         | feels that this is a great match, and that this data structure
         | very well fits the language as it was intended.
        
         | hinkley wrote:
         | > We can free them more quickly in one go when needed. We can
         | group objects by lifetime using them. Having thread-local
         | arenas naturally separates thread-local allocations from
         | program-global allocations.
         | 
         | These are at odds due to concurrency and object lifetimes.
         | Reaching into memory allocated by another thread on another
         | core was never free but has only gotten more costly.
         | 
         | You can either pay more at allocation time, use time, or have a
         | copying collector. But you have to deal with at least one.
         | 
         | So for a cache or a lazily loaded lookup table, you want an
         | arena allocator. But the same data structure used within the
         | scope of say a single request should be a thread local arena.
        
         | sirwhinesalot wrote:
         | Yes, you can have memory safe arenas in Rust, as with Bumpalo.
        
         | alextingle wrote:
         | This approach to memory management is completely at odds with
         | the whole point of Rust.
         | 
         | Object orientated programming has conditioned programmers into
         | believing that having a hairy nest of small allocations, all
         | with pointers to each other, is the normal, unavoidable
         | situation.
         | 
         | In fact, it creates all sorts of problems. First, and most
         | obviously, it's really hard to keep track of all those
         | allocations, so you get leaks, and use after free, and all the
         | other familiar memory bugs. But you also get bloated memory
         | use, with both your user code, and the allocator having to keep
         | track of all those chunks of memory. You get poor cache
         | utilisation. You incur often ridiculous CPU overhead
         | constructing and tearing down these massive, intricate
         | structures.
         | 
         | Rust makes it harder to trip over the memory bugs, but that
         | makes it easier to keep on using the lots-of-tiny-allocations
         | paradigm, which is a much bigger problem overall.
        
       | HarHarVeryFunny wrote:
       | I don't see this as very well conceived article, since the two
       | concepts being discussed, manual memory management, and arena
       | allocators are really orthogonal.
       | 
       | Arena allocators aren't going to save you from memory management
       | bugs, and aren't intended to. They are just an efficient may to
       | allocate and free a bunch of chunks of memory that have the same
       | lifetime, for example due to belonging to the same data
       | structure. The idea is that you just sequentially allocate from a
       | large chunk of memory, then free up the entire large chunk in one
       | go at the end of the collective lifetime of the allocated pieces.
       | 
       | The things that make memory management in C error-prone are that:
       | 
       | 1) C doesn't have objects/destructors, so all freeing of memory
       | is manual, thereby creating the possibility that you mess it up.
       | 
       | 2) C's pointers don't have ownership semantics, and therefore
       | also doesn't have niceties like shared ownership (cf C++'s shared
       | vs unique pointers). All ownership tracking is manual, giving you
       | another chance to mess up.
       | 
       | The only think that is going to save you from memory management
       | errors in C is programmer discipline and attention to detail.
        
       ___________________________________________________________________
       (page generated 2025-06-28 23:01 UTC)