top | item 47160477

(no title)

mattclarkdotnet | 4 days ago

Sorry if this is obvious to Java experts, but much as parallel GC is fine for batch workloads, is there a case for explicit GC control for web workloads? For example a single request to a web server will create a bunch of objects, but then when it completes 200ms later they can all be destroyed, so why even run GC during the request thread execution?

discuss

order

noelwelsh|3 days ago

There are a few ways of looking at this:

- Purely on the JVM, you probably want ZGC (or Shenandoah) because latency is more important than throughput.

- On Erlang / the BEAM VM, each thread gets its own private heap, so GC is a per thread operation. If the request doesn't spill over the heap then GC would never need to run during a request handler and all memory could be reclaimed when the handler finishes.

- There can still be cases where a request handler allocates memory that is no solely owned by it. E.g. if it causes a new database connection to be allocated in a connection pool, that connection is not owned by the request handler and should not be deallocated when the handler finishes.

- The general idea you're getting at is often called "memory regions": you can point to a scope in the code and say "all the memory can be freed when this scope exits". In this case the scope is the request handler. It's the same idea behind arena or slab memory allocation. There are languages that can encode this, and do safe automatic memory management without GC. Rust is an obvious example, but I don't find it very ergonomic. I think the OxCaml [1] and Scala 3 [2] approaches are better.

[1]: https://oxcaml.org/documentation/stack-allocation/reference/

[2]: https://docs.scala-lang.org/scala3/reference/experimental/cc...

hinkley|3 days ago

See also arena allocation, for realtime systems. But those systems typically require that any task have a reasonably tight upper bound on memory usage.

mattclarkdotnet|3 days ago

Thank you, that’s what I came here to learn!

jacobn|4 days ago

Most web request cases where you care about performance probably have multiple parallel web requests, so there’s no clean separation possible?

mattclarkdotnet|3 days ago

Sure, but each request has its own context. Shared resources like DB connection pools will be longer lived but by definition they aren’t alllcated by the request thread. So why not simply exempt everything allocated by a request thread from GC, and simply destroy it on request completion?