This is actually a question for the book "Java Performance", where the author mentioned:
Garbage collecting the young generation space prior to garbage collecting the old generation space usually results in less work for the garbage collector and more objects being garbage collected since objects in the old generation space may be holding object references to objects in the young generation space. If the young generation space is not garbage collected, any object in the old generation space that holds a reference to an object in young generation space cannot be garbage collected.
I feel the bold sentence is incorrect. I think he actually meant that, if the young generation space is not garbage collected, any object in the old generation space that is referenced by(rather than holds a reference to) an object in the young generation space cannot be garbage collected.
What do you think?
I think he actually meant that, if the young generation space is not garbage collected, any object in the old generation space that is referenced by(rather than holds a reference to) an object in the young generation space cannot be garbage collected.
I agree with you. Probably just a typo.
Related
What is the the difference between
--max-old-space-size vs --max-semi-space-size in the Nodejs docs?
I understand that they are related to V8 garbage collector, but there doesn't seem to be any clear explanation within the docs.
Garbage collection is the process of reclaiming the memory occupied by
objects that are no longer in use by the application. Usually, memory
allocation is cheap while it’s expensive to collect when the memory
pool is exhausted.
An object is a candidate for garbage collection when it is unreachable
from the root node, so not referenced by the root object or any other
active objects. Root objects can be global objects, DOM elements or
local variables.
The heap has two main segments, the New Space and the Old
Space. The New Space is where new allocations are happening; it
is fast to collect garbage here and has a size of ~1-8MBs. Objects
living in the New Space are called Young Generation. The Old Space
where the objects that survived the collector in the New Space are
promoted into – they are called the Old Generation. Allocation in the
Old Space is fast, however collection is expensive so it is
infrequently performed .
--max-old-space-size is related to the Old Space limit whereas max-semi-space-size is related to the New Space.
New Space has a smaller buffer (as the GC runs more frequently) whereas Old Space is larger and runs less often.
source: risingstack garbage collection.
source: hunting a ghost
Will jvm old gc mark all the heap or just old heap ? Because the young generation
objects can contains old generation objects .
It depends on the the collector that you use.
Some collectors do not use any structure to records the references from young generation to old generation. In theory, these collectors must scan the young generation to find the garbage. However, some collectors will execute minor gc instead of scan the young generation. Like CMS(Concurrent Mark Sweep), it will scan the young generation. But you can use options
-XX:+ScavengeBeforeFullGC -XX:+CMSScavengeBeforeRemark
to collect young generation before doing full gc or CMS remark phase.
But some collectors don't need to scan young generation. They usually use some data structures to record the references, Like G1(Garbage First) collector. It use the RS(remember set). The G1 collector will scan the RS to find out the reference. For instance, if there is a young region call yr1, has a reference points to an object in the old region or1. The RS will add a record like:
yr1 -> or1
(The actual implementation of RS is really complicated)
So, in mark cycle, G1 will scan the RS to find out all the reference points to the or1.
More detail:
hotspot-virtual-machine-garbage-collection-tuning-guide
memorymanagement-whitepaper
G1-One-Garbage-Collector-To-Rule-Them-All
Garbage first Collection
When I read the book 《The Garbage Collection HandBook》, the chapter 9
impile that:"object lifetimes are better measured by the number of bytes of heap space allocated between their birth and death.". I am not very understand this sentence. why lifetime can be measured by the allocated bytes? I try to google for that, but I get no answer.
Who can explain that to me? Thanks!
By measuring object lifetimes in terms of bytes allocated between instantiation and death, it is easier for the GC algorithm to adapt to program behaviour.
If the rate of object allocation is very slow, a simple time measurement would show long pauses between collections, which would appear to be good. However, if the byte allocation measurement of object lifetimes is high objects may be getting promoted to a survivor space or the old generation too quickly. By measuring the byte allocation the collector could optimise heap sizes more efficiently by expanding the young generation to increase the number of objects that become garbage before a minor collection occurs. Just using time as this measure would not make the need for the heap resizing obvious.
As the book points out, with multi-threaded applications it is hard to measure byte allocation for individual threads so collectors tend to measure lifetimes in terms of how many collections an object survives. This is a simpler number to monitor and requires less space to record.
“time” is only a scale that allows to bring an order to events. There are many possible units, even in the real world. Inside the computer, for the purpose of garbage collection, there is no real world’s time unit needed, all the garbage collector usually wants to know, is, which object is older than the other.
For this purpose, just assigning an ascending number to each allocated object would be sufficient, but this would imply maintaining an additional counter. In contrast, the number of allocated bytes comes for free. It’s important that we accumulate the allocated bytes only, never subtracting deallocated bytes, so we have an always growing number.
In a generational memory management, this number doesn’t need to be updated on every allocation, as objects are allocated continuously in a dedicated space, so their addresses represent their relative age within this memory region whereas the start of the region is associated with the last garbage collection. Only when the garbage collector runs and moves the surviving objects, it has to merge this information into an absolute age, if needed.
Implementations like the HotSpot JVM simplify this further. For surviving objects, it maintains a small counter holding the number of garbage collection cycles it survived. After having survived a configurable number of collection cycles, it gets promoted to the old generation and beyond that point, the object’s age becomes irrelevant.
Can anybody explain the concept of card table and write barriers in Garbage Collection process in .Net?
I really can't get the explanation of these terms i.e what are they,how are they useful and how do they paticipate in GC.
Any help would be really appreciated.
The card table is an array of bits, one bit for each chunk of 256 bytes of memory in the old generation. The bits are normally zero but when a field of an object in the old generation is written to, the bit corresponding to the objects memory address is set to one. That is called executing the write barrier.
The garbage collector in .NET is generational and has a phase which only traces and collects objects in the young generation. So it goes through the object graph starting with the roots but does not recurse into objects in the old generation. In that way, it only traces a small fraction of the whole object graph.
To find the roots to start tracing from, it scans the programs local and global variables for young generation objects. But it would miss objects only referenced from old generation objects. Therefore it also scans fields of objects in the old generation whose card table bit is set.
Then after the young generation collection is complete it resets all card table bits to zero.
Please feel free to correct me if I am wrong. In JVM heap, there are two generations, old and young. When doing full GC, in old generation, there are heavy operations like compact spaces and fixing the hole, which will make JVM hang. And I find in young generation, a light weighted GC is applied, and there are another area called Eden involved in young generation from my search results. However, after search a lot of documents, I still have two confusions about GC in young generation,
In young generation, it seems GC does not work in the way which old generation GC works (i.e. old generation GC compact and fixing the hole)? If so, how did GC in young generation works?
What is Eden space and how this space is utilized in young generation? Appreciate if any document for a newbie could be recommended.
This is the single, most important diagram you have to memorize and understand:
(source: oracle.com)
It comes from Java SE 6 HotSpot[tm] Virtual Machine Garbage Collection Tuning, one stop place to learn everything about GC internals. But to address your immediate questions:
Allocating new objects using new operator (almost) always happens in Eden space. But Eden is actually a stack. When you create new object needing N bytes, single pointer advances by N bytes on that stack and that's it. Allocating is that fast, no searching for free spot, compacting, whatever.
Of course this stack is not infinite, at some point we'll reach its end, triggering minor GC. Also most likely multiple objects are already garbage. So what JVM does in minor GC is the following:
traverse graph of objects starting from GC roots
copy all objects reachable from GC roots to one of survivor spaces (no gaps, we know all of them and this is a single process)
wipe out eden space (basically just moving this stack pointer back to 0)
In subsequent minor collections there are additional steps:
one of survivor spaces is examined as well. Live objects from both eden and one of survivor spaces are copied to second survivor space. This means there is always exactly one free survivor space.
So how are objects ending in tenured generation? First young objects are copied to one of survivor spaces. Then they are copied to the other and again and again. Once given object jumps back and forth too many times (configurable, 8 by default), it is promoted to tenured space.
Major GC runs when tenured space is full.