News for hackers. Stuff that matters.
Re:Garbage Collection for Systems Programmers by pron on Saturday March 30, 2024 @12:00PM (#39876083)
That's not at all a rare special case in most server applications.

One way to see that is to consider how much of a program's working set is in threads' stacks vs the heap. If the most of the working set is in the heap, there's usually some non-trivial object lifetimes involved (i.e. cases where lifetimes can be encapsulated and abstracted away from client code). Yes, sometimes all of these can be taken care of by arenas (and there are languages, like Zig, that strive to be very arena-friendly), but that -- i.e. the case where all objects are easily arena-able -- is not the more common scenario.

Re:Garbage Collection for Systems Programmers by flohofwoe on Saturday March 30, 2024 @12:11PM (#39876171)
Depends on the type of server I guess. I can easily imagine a situation where all allocations of a request are handled through a simple bump allocator, and once the request is done, the bump allocator is reset instead of 'freeing' each individual allocation.
Re:Garbage Collection for Systems Programmers by cogman10 on Saturday March 30, 2024 @02:40PM (#39877456)
This would only work for fairly trivial applications. The moment you start adding things like http clients or databases you have to start considering having connection pools with lifetimes that don't strictly match a request lifecycle.

Not saying such an application doesn't exist, it certainly does.

Re:Garbage Collection for Systems Programmers by ncruces on Saturday March 30, 2024 @02:46PM (#39877505)
That “simple bump allocator” is basically allocating everything on the thread's stack, as the GP mentioned.

It's what you put on the heap that has complex lifetimes. Sometimes you can fix that with an arena. If you can't, you probably can't figure out when the last reference to it dies either.

Re:Garbage Collection for Systems Programmers by jayd16 on Saturday March 30, 2024 @03:15PM (#39877717)
How did we go from "this is the most common case" to "I can imagine it?" Sure there are cases where a request can be handled by the stack but the point is that the more complex case is extremely common.

Any kind of background/asynchronous work spawned from a request and your plans are shot.

Re:Garbage Collection for Systems Programmers by thefaux on Saturday March 30, 2024 @07:08PM (#39879548)
Yes and that is yet another case for encapsulation.

For me, it is an antipattern for a short lived task to be directly creating long lived resources. Async work ideally is scheduled using message passing to the task manager which may have its own memory management strategy (heck, the background task may well be written in an entirely different language).

I just feel that it is very common to have large portions of the application that fit the model of read input/write output, free all intermediate data upon completion. Due to a lack of encapsulation, however, we put unnecessary pressure on the allocator or garbage collector by mixing the short and long lived parts of our applications.

Re:Garbage Collection for Systems Programmers by pron on Sunday March 31, 2024 @10:00AM (#39884333)
> we put unnecessary pressure on the allocator or garbage collector by mixing the short and long lived parts of our applications.

That is not how modern tracing GCs work, though. First, modern tracing GCs don't do any work to actively free any dead object (they don't even need to know about them). They work to compact the live ones. Second, modern tracing GCs automatically separate short-lived from long-lived objects and preserve them in different ways.

While it's true that in principle a programmer could find a technique to optimally manage memory in a given program and that even a good GC would never be quite as optimal, in practice a GC would do a better job than you could unless you spend an inordinate amount of time figuring out the optimal strategy; furthermore, the optimal strategy has to contend with non-local effects, i.e. a change in one subroutine might have a global effect on what the optimal global strategy is.

So as a first approximation, a good tracing GC will give you better memory management (performance-wise) per unit of programmer effort, and if you want even better performance -- give the GC more RAM. You're trading off RAM for less work on your part.