What is the purpose of Survivor Space in Java memory?
Asked Answered
A

1

6

Tried looking up for this, but all the questions/answers I came across talk about the purpose of having 2 survivor spaces. I would like to understand the purpose of having survivor space in general. How does moving objects from Eden to Survivor benefit?

Auspice answered 15/8, 2020 at 22:9 Comment(4)
#47504642Gynophore
@Gynophore that should be a duplicate, but unfortunately none of its answers actually answer the question.Millsaps
@Millsaps I think the most voted answer to that question suits to this question as well. That question says why there are 3 types of spaces and this questio asks about existence of one of those 3 typesGynophore
@Gynophore no, none of the answers even mention that there are three, let alone explain it.Millsaps
C
12

Performance.

In general, splitting the heap ( be that generational or any other discriminator ), was seen as a rather good thing, not all collectors follow that though ( Shenandoah is not such a collector for example ).

Why is that good thing? It takes time to scan the entire heap for alive Objects. How do you tell your garbage collector - "time to run now". When is that time? You could say : run after every 100-th allocated Object. Is that too soon? ( what if the size of these objects is only a tiny fraction of the heap ) or worse : is it too late? What if you say: trigger a collection at 65% of the heap occupancy ( G1 triggers a major collection at that percentage, among other possibilities, by default ). What if at that 65% you find out that the majority of Objects should have been collected a lot earlier, they have been staying in the heap for far too much time.

You can see that this becomes complicated fast. Things get worse when you understand that scanning the heap takes time, and the last thing you want is for you application to stall, when GC is running. But please also bear in mind that there are collectors that scan the heap concurently, so they don't have this problem ( Shenandoah, ZGC or C4 ).

If you could separate the heap, you could scan only a portion of it, thus taking little time. People call them "minor" collections. Some collectors thus divide the heap in "young" and "old", this separation comes on the premises of "infant mortality" : young objects die fast. Thus, if you do this separation + young objects die soon, you can scan only a certain portion of the heap and in the majority of cases only deal with that. This also simplifies the answer of : when a GC is supposed to run? When young is full, of course.

And now to your direct point: why is a Survivor needed, at all. Let's assume it isn't there. The first GC cycle happens ( young region is full, let's call it Eden to be exact), what happens next? GC needs to tell what is alive there, move it to "old generation", clear Eden and start allocating again. Second cycle comes in and does the same thing and so on, until GC says : "old generation if full, I can't move anymore". This is the place where an famous "old generation" happens. It's usually costly.

But we do know about "infant mortality" here. We do know that the second and third GC cycle moved some objects to the old generation that would have been collected at the fourth phase. This opportunity was missed. As such : Survivor space. It keeps objects in there for "a little longer" then a single GC cycle ( called survivor age ), knowing that in the nearest future this will become garbage. Thus, no need to scan the old often, only scan and take care of a smaller portion of the heap (Eden and Survivor ). As to why there are two Survivor spaces, its a separate question...

In reality, latest GCs don't need that. They found a way to scan the heap concurently, while your application is running, so they don't have these spaces. The premises of young death still exists, and some GC algorithms might use that; now or in the future.

Courtly answered 16/8, 2020 at 4:2 Comment(7)
Thanks for the answer, Eugene. Further on that, It keeps objects in there for "a little longer" : Suppose there is no Survivor space, Eden would be have larger memory space allocated. This should result in objects being kept a little longer before minor GC is triggered. So how would the Survivor space does a better job of keeping the objects "a little longer" ?Auspice
@Auspice compactation. It you do that your Eden is going look like swiss chess : wth holes in it. You will soon end up in a situation where objects cant be allocated anymore because there is no contiguous space and "defragmention" will need to happen. A Survivor space gets rid of this problem by copying objects, so at the next cycle Eden ( and one Survivor space) is empty.Courtly
The "aging" strategy could be as well implemented within a single Eden. Survived objects can be moved to the beginning of the Eden space (just like how compaction works in the old generation). But implemeting compaction is a bit harder and takes a bit more time comparing to copying into an always-empty space. So, the Survivor is an optimization which trades a little heap space for the faster and simpler young collections.Magda
@Eugene & @apangin - Thank you. if compactation was the reason, then we only need 1 survivor space (or call it Eden2). When minor GC occurs, move reachable objects to Eden2 and call Eden2 as the primary Eden and keep Eden1 empty (like how Survivor1 and Survivor2 functions currently). [continued..]Auspice
[..continued] The only reason I can think of why moving items from Eden1 to Eden2 would be not desirable, is if the cost to access Eden2 is higher than Eden1 (I cant think why this would be. Is it not possible to have 2 memory spaces at equal reachable distance/cost?) and that JVM assumes/expects the younger(recently created) objects to be accessed more frequently. Also, are there any references which talks about why the GC algorithm was implemented this way? I see many references talking about how GC is implemented, but why is not clear.Auspice
@Auspice Yes, having just 2 survivor spaces (and no eden) is also possible, but implies much larger memory waste (50% of young generation). With 2 small survivor spaces in addition to eden, the memory waste is usually around 12.5% of young generation, with the same level of performance.Magda
@Auspice mind that older garbage collection implementations had a more rigid memory organization. For an implementation like G1GC which assigns memory blocks to these spaces on-the-fly, it doesn’t matter whether you consider Eden and the non empty Surivior Space as a single source entity. When it comes to the copying process, they are just sources, but when it comes to allocation, the memory blocks of the previous collection’s target survivor space are occupied by objects, hence, unusable, so you can distinguish them from blocks that you can fill with new objects (part of Eden space).Ryle

© 2022 - 2024 — McMap. All rights reserved.