[HN Gopher] Mark-Scavenge: Waiting for Trash to Take Itself Out
___________________________________________________________________
Mark-Scavenge: Waiting for Trash to Take Itself Out
Author : vips7L
Score : 67 points
Date : 2024-11-24 17:40 UTC (5 hours ago)
(HTM) web link (inside.java)
(TXT) w3m dump (inside.java)
| A4ET8a8uTh0 wrote:
| What a time to be alive, I read it the opening fully expecting to
| see an open source automated trashcan that takes itself to the
| curb each Monday. I was disappointed to find out it is about an
| actual garbage collection algorithm.
| garblegarble wrote:
| I know this is completely off-topic, but you might be
| interested in this[1] YouTuber who did something not far off
| that...
|
| 1: https://www.youtube.com/watch?v=VhYEOG9LOIk
| kibwen wrote:
| _> Modern garbage collection assumes that the weak generational
| hypothesis holds and that most objects die young_
|
| Aside, I'm curious how first-class support for value types and
| Go-style stack allocation via escape analysis changes the value
| proposition of the generational hypothesis. If we hypothesize
| that short-lived objects are local to a single function scope
| (and thus eligible for stack allocation either explicitly via a
| value type or heuristically via escape analysis) then it might
| completely upend the generational hypothesis and make it so that
| relatively more long-lived objects are getting heap-allocated.
| Surely someone's done some studies on this?
| DamonHD wrote:
| AFAIK not nearly enough stuff gets caught by escape analysis -
| and thus stack allocated - to make a difference.
| kibwen wrote:
| I'm open to believing that this is true, but some real
| numbers would be nice. Surely it wouldn't be a hugely
| invasive change to fork the Go compiler, change the stack
| allocation check to `return false`, and then measure the
| overhead of the garbage collector on real Go programs with
| stack allocation both enabled and disabled.
| DamonHD wrote:
| I may have been answering past you - I am thinking of Java
| running on the JDK here. And indeed I may be out of date
| also.
| cempaka wrote:
| Yeah in Java land specifically I think the question would
| become, "does the generational hypothesis still hold up
| once we have Valhalla and a much larger share of short-
| lived objects are stack allocated as value types?" but of
| course it may be years until the ecosystem reaches that
| point, if ever.
| neonsunset wrote:
| As shown by C#, it will generally continue to be relevant
| since both primarily use JIT compilation with ability to
| modify code at runtime which can violate inter-procedural
| escape analysis assumptions leading to heap allocations
| of the objects that are passed down to the callees (there
| is work scheduled for .NET 10 to address this, at least
| for AOT compilation where interproc analysis conclusions
| will be impossible to violate).
|
| You can craft a workload which violates the hypothesis by
| only allocating objects that live for a long time but
| both JVM and .NET GC implementations are still much
| faster designs than Go's GC which prioritizes small
| memory footprint and consistent latency on _low_
| allocation traffic (though as of .NET 9, SRV GC puts much
| more priority on this, making similar tradeoffs).
| cempaka wrote:
| > _ability to modify code at runtime_
|
| Would Java's moves towards "integrity by default" mean
| that this could be ruled out in more cases?
| DamonHD wrote:
| Ahem --- JDK => JVM!
| DarkNova6 wrote:
| The reason escape analysis is not "good enough" is why we
| have project Valhalla trying to bring Value Types into the
| JVM.
|
| I don't have numbers at hand, but I remember the JDK Expert
| Group talking about this extensively in the past and why
| they deferred bringing Value Types for such a long time.
| They hoped complex enough EA can get rid of indirections
| and heap allocations but it just wasn't powerful enough,
| even with all advances throughout the years.
| fweimer wrote:
| Historically, Hotspot's escape analysis only resulted in
| avoided heap allocations (via scalar replacement) if all uses
| were inlined. I don't think this has changed.
| eikenberry wrote:
| Is there a language that makes this explicit, allocates the
| variables on the stack via compiler enforced notation?
| fanf2 wrote:
| C, C++, Rust, Zig, ...
| neonsunset wrote:
| C# (.NET in general) :)
|
| Well, variables cannot be forced to stack specifically.
| They are placed in the "local scope". And that would
| usually be either stack or CPU registers - thinking in
| stack only is a somewhat flawed mental model.
|
| Both C# and F# complicate this by supporting closures,
| iterator and async methods which capture variables placing
| them in a state machine box / display class instead which
| would be located on the heap, unless stack-allocated by
| escape analysis (unlikely because these usually cross
| method boundaries).
|
| However, .NET has `ref structs` (or, in F#, [<Struct;
| IsByRefLike>] types) which are subject to lifetime analysis
| and can never be placed on the heap directly or otherwise.
| masklinn wrote:
| Go has much more significant stack allocation capabilities,
| most notably it has no problem allocating entire structs on
| the stack so doesn't need scalar replacement, which falls
| over if you breathe on it
| (https://pkolaczk.github.io/overhead-of-optional/).
|
| According to https://github.com/golang/go/discussions/70257#d
| iscussioncom...
|
| > the weak generational hypothesis does not hold up well with
| respect to heap-allocated memory in many real-world Go
| programs (think 60-70% young object mortality vs. the 95%
| typically expected)
| DarkNova6 wrote:
| But stack allocated objects are not part of the heap and
| therefore not even part of Garbage Collection? And afaik stack
| allocation is already done for objects which don't escape a
| method.
| masklinn wrote:
| > it might completely upend the generational hypothesis
|
| The generational hypothesis is about object lifetime, and that
| doesn't change.
|
| It does change the relevance of the generational hypothesis to
| garbage collection.
|
| > Surely someone's done some studies on this?
|
| The go team has, and that's why go doesn't have a generational
| GC. The complexity of adding generational support, especially
| in a mutation-based language (so needing memory barriers and
| the like) was found not to benefit when a significant fraction
| of the newborn objects don't even reach the youngen. See
| https://github.com/golang/go/discussions/70257#discussioncom...
| from the current discussion of adding opt-in ad-hoc support for
| memory regions.
| uluyol wrote:
| You might be interested in this talk:
| https://go.dev/blog/ismmkeynote
| ithkuil wrote:
| If you flip the argument on its head you can frame it as: since
| most objects die young it's very likely they will stay on the
| stack and thus it makes sense to invest in an allocation-site
| optimizer that will put the object on the heap only if static
| escape analysis says it may escape the lexical scope.
| fweimer wrote:
| How does this relate to Shenandoah's region selection logic?
| Doesn't it have similar behavior?
___________________________________________________________________
(page generated 2024-11-24 23:00 UTC)