tag:blogger.com,1999:blog-7735872642513631302.post3298704798548496054..comments2023-07-15T17:54:51.492+01:00Comments on Alexey Ragozin: Understanding GC pauses in JVM, HotSpot's minor GC.Alexey Ragozinhttp://www.blogger.com/profile/13720493857045012756noreply@blogger.comBlogger35125tag:blogger.com,1999:blog-7735872642513631302.post-14908865519322325882019-11-22T11:56:55.978+00:002019-11-22T11:56:55.978+00:00Good questions. I do not know exact answer. Some i...Good questions. I do not know exact answer. Some implementations are using bitmap for that purpose.<br />Though, I think bit manipulation would require more instructions for write barrier. In addition, I believe extra values of byte may be used during CMS concurrent preclean phase.Alexey Ragozinhttps://www.blogger.com/profile/13720493857045012756noreply@blogger.comtag:blogger.com,1999:blog-7735872642513631302.post-41794750385983694152019-11-22T08:01:43.552+00:002019-11-22T08:01:43.552+00:00Great article! I have a question. If card table is...Great article! I have a question. If card table is just used to mark a 512Bytes page is dirty or clean, a bit is enough, why a byte is needed?Anonymoushttps://www.blogger.com/profile/04816447360335350748noreply@blogger.comtag:blogger.com,1999:blog-7735872642513631302.post-53824591780343161102018-05-15T06:50:56.070+01:002018-05-15T06:50:56.070+01:00At step (4) all objects in young space are physica...At step (4) all objects in young space are physically moved to surviviour space, so object A would be updated with new address of B and thus marked as dirty.Alexey Ragozinhttps://www.blogger.com/profile/13720493857045012756noreply@blogger.comtag:blogger.com,1999:blog-7735872642513631302.post-48887658809300769452018-05-14T20:18:09.633+01:002018-05-14T20:18:09.633+01:00Hi. I have a question. When object gets to old fro...Hi. I have a question. When object gets to old from young it is marked as Dirty card (right?). Let's suppose that:<br />1. Object A is live and is reffering to Object B (in young collection)<br />2. After GC Object A is promoted to old (so is marked as dirty card).<br />3. Object A is not modified, but because it was marked as dirty card, Object B is still live, because of Object A.<br />4. Another GC -> Cards are reset.<br />5. Object A was not modified, so is not marked as dirty card.<br />6. Object B is deleted?<br /><br />Are old object marked somehow if they were found to have a reference to young object?<br /><br />Or maybe when objects are copied to one of survivor space, the references to them were changed, therefore objects in old generation were modified and marked as dirty cards?Anonymoushttps://www.blogger.com/profile/07317015854230822802noreply@blogger.comtag:blogger.com,1999:blog-7735872642513631302.post-61533059097187905452018-03-06T17:38:56.655+00:002018-03-06T17:38:56.655+00:00There are no pages. Each page is just DIRTY/CLEAN ...There are no pages. Each page is just DIRTY/CLEAN flag value in card table. There DIRTY means - corresponding 512 bytes of heap may contain object reference modified since last card table reset.Alexey Ragozinhttps://www.blogger.com/profile/13720493857045012756noreply@blogger.comtag:blogger.com,1999:blog-7735872642513631302.post-27769319657366752402018-03-06T10:08:25.738+00:002018-03-06T10:08:25.738+00:00Thank you, Alexey!
Before i asked the question l...Thank you, Alexey! <br /><br />Before i asked the question last night, i have misunderstood this topic. "512 bytes" should be the threshold value of memory page which is aimed to record the memory size of Regular Java object. So, i think 512 bytes is enough for recording.<br />Anonymoushttps://www.blogger.com/profile/17997776560913341532noreply@blogger.comtag:blogger.com,1999:blog-7735872642513631302.post-35973067055170078532018-03-05T13:22:05.822+00:002018-03-05T13:22:05.822+00:00If it is regual Java object page of first object&#...If it is regual Java object page of first object's byte is marked. If it is Object[] page containing element being written is marked. Alexey Ragozinhttps://www.blogger.com/profile/13720493857045012756noreply@blogger.comtag:blogger.com,1999:blog-7735872642513631302.post-78757694386913533552018-03-05T11:23:28.353+00:002018-03-05T11:23:28.353+00:00As it shows above(Writer Barrier), 512byte is the ...As it shows above(Writer Barrier), 512byte is the threshold value of memory block. If i have an object (2MB), what can JVM do about it?Anonymoushttps://www.blogger.com/profile/17997776560913341532noreply@blogger.comtag:blogger.com,1999:blog-7735872642513631302.post-1493341050824583812017-05-16T18:46:05.019+01:002017-05-16T18:46:05.019+01:00It depends on GC type. In MSC full collection is t...It depends on GC type. In MSC full collection is triggered if free space in old gen below projected promotion volume. In CMS, there is occupancy threshold, by promoting objects young GC increasing old space occupancy and my trigger old collection cycle. In G1, there are no old space collections, mixed collection collect young space and portion of old space (full GC may happen as resort though).Alexey Ragozinhttps://www.blogger.com/profile/13720493857045012756noreply@blogger.comtag:blogger.com,1999:blog-7735872642513631302.post-33004750781559523802017-05-16T09:45:05.105+01:002017-05-16T09:45:05.105+01:00Hi Alexey,
Thanks for the article. Could you tel...Hi Alexey,<br />Thanks for the article. Could you tell me when minor gc will cause major gc ? Anonymoushttps://www.blogger.com/profile/03608740144688296827noreply@blogger.comtag:blogger.com,1999:blog-7735872642513631302.post-10329745827952520332017-02-18T19:31:13.839+00:002017-02-18T19:31:13.839+00:00All references from young to old are considered GC...All references from young to old are considered GC roots for old collection.<br />Alexey Ragozinhttps://www.blogger.com/profile/13720493857045012756noreply@blogger.comtag:blogger.com,1999:blog-7735872642513631302.post-78060768426322290142017-02-18T19:25:11.115+00:002017-02-18T19:25:11.115+00:00How are young to old cross generation references h...How are young to old cross generation references handled ? Does the old gen gc follow the same card marking technique ?<br />Anonymoushttps://www.blogger.com/profile/03663933134542390465noreply@blogger.comtag:blogger.com,1999:blog-7735872642513631302.post-72212844989278583492016-11-08T08:18:11.153+00:002016-11-08T08:18:11.153+00:00I reality card scanning and object relocation are ...I reality card scanning and object relocation are running in parallel (once thread encounters next dirty card it immediately scans page and process all young reference recursively), so you cannot time them separately.Alexey Ragozinhttps://www.blogger.com/profile/13720493857045012756noreply@blogger.comtag:blogger.com,1999:blog-7735872642513631302.post-55272838369115189082016-11-04T21:28:53.587+00:002016-11-04T21:28:53.587+00:00Very good article.
We can use some tools to meas...Very good article. <br /><br />We can use some tools to measure the young GC time and full GC time. Can I ask how can we decompose the young GC time into details? Using which parameter or what tools or anything else? Thanks.<br /><br /><br />Tonyhttps://www.blogger.com/profile/09916479088950811995noreply@blogger.comtag:blogger.com,1999:blog-7735872642513631302.post-40348942951798647782016-09-25T06:31:38.614+01:002016-09-25T06:31:38.614+01:00GC threads are scanning card table. If dirty flag ...GC threads are scanning card table. If dirty flag is found in card table, corresponding page of old space should be scanned to find actual references to young objects.Alexey Ragozinhttps://www.blogger.com/profile/13720493857045012756noreply@blogger.comtag:blogger.com,1999:blog-7735872642513631302.post-88854800208638211462016-09-24T10:56:53.645+01:002016-09-24T10:56:53.645+01:00Hi Alexey,
Thanks for the article. I have one conf...Hi Alexey,<br />Thanks for the article. I have one confusion here.<br /><br />After reading this <br />"Normally collection of all reference from old space will require scanning through all objects in old space. That is why we need write-barrier. All objects in young space have been created (or relocated) since last reset of write-barrier, so non-dirty pages cannot have references into young space. This means we can scan only object in dirty pages."<br /><br />I am unable to understand why we have Tcard_scan as well as Told_scan while calculating time for young collection. <br /><br />Do you mean first look to card table and find a old object and then do old scan to find references of that old object to young gen object ?Anonymoushttps://www.blogger.com/profile/02242052160577869866noreply@blogger.comtag:blogger.com,1999:blog-7735872642513631302.post-88337959487191608872016-01-05T11:05:25.678+00:002016-01-05T11:05:25.678+00:00I'll answer second question first
2) If objec...I'll answer second question first<br /><br />2) If object is relocated/promoted its new address is stored at old location (at object header). During GC EVERY reference pointing to young space is processed and rewritten with new object location.<br /><br />1) There are two activities related to card table happen during young GC. Reference scanning tasks are clearing cards as memory is being scanned. Though if reference to object is rewritten (due to its relocation), card is marked dirty again. Every live object form young space is being relocated, so right after young GC, every memory page containing references to survived young objects is marked as dirty.Alexey Ragozinhttps://www.blogger.com/profile/13720493857045012756noreply@blogger.comtag:blogger.com,1999:blog-7735872642513631302.post-38592930940626021252016-01-05T10:44:37.202+00:002016-01-05T10:44:37.202+00:00Hi Alexey,
thanks for great explanation. Could yo...Hi Alexey,<br /><br />thanks for great explanation. Could you clarify a few points for me please?<br />1) After young gc is complete, are all pages in the card table "clean"? Or are some pages still dirty, because they still point to objects from young generation?<br />2) When objects are relocated or promoted, how does JVM know, which references point to a particular object. Does an object maintain a list of objects it is referenced from?damluarhttps://www.blogger.com/profile/05425803973033514785noreply@blogger.comtag:blogger.com,1999:blog-7735872642513631302.post-25539103105455532552013-12-04T11:30:49.763+00:002013-12-04T11:30:49.763+00:00Default GC algo depends on -client / -server flags...Default GC algo depends on -client / -server flags and some hardware heuristics.<br /><br />Most likely it would parallel scavenge + parallel old combination.<br /><br />But instead of guessing you can easily check in JConsole. Alexey Ragozinhttps://www.blogger.com/profile/13720493857045012756noreply@blogger.comtag:blogger.com,1999:blog-7735872642513631302.post-74056490848301729622013-12-04T08:51:35.920+00:002013-12-04T08:51:35.920+00:00Hi Alexey,
Great article. the only best article i...Hi Alexey,<br /><br />Great article. the only best article i found on net. just want to know what is the default collectors for each generation in java 7?<br /><br />ThanksSameerhttps://www.blogger.com/profile/09182495564624291772noreply@blogger.comtag:blogger.com,1999:blog-7735872642513631302.post-56738107483934342682013-11-14T03:49:24.268+00:002013-11-14T03:49:24.268+00:00Great article. Thanks for putting this together!Great article. Thanks for putting this together!Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-7735872642513631302.post-30423403562628326322013-10-07T17:46:11.183+01:002013-10-07T17:46:11.183+01:00In this case you should either shrink survivor spa...In this case you should either shrink survivor space (-XX:SurvivorRatio=N) or use -XX:MaxTenuringThreshold=N to set max age for object in young space.Alexey Ragozinhttps://www.blogger.com/profile/13720493857045012756noreply@blogger.comtag:blogger.com,1999:blog-7735872642513631302.post-89704601767572320582013-10-07T15:48:22.154+01:002013-10-07T15:48:22.154+01:00Thank you, Alexey.
We are using 64 bit JVM. From ...Thank you, Alexey.<br /><br />We are using 64 bit JVM. From GC log, I can see this:<br /><br />Desired survivor size 536870912 bytes, new threshold 16 (max 31)<br /><br />So I assume Max age is 31 instead of 15 in 64 bit JVM.<br /><br />My problem with Minor GC is that it won't overflow, so that some very old objects are kept being scanned again and again, for up to hours.<br /><br />Thanks,<br />JeffAnonymoushttps://www.blogger.com/profile/10604466177025085730noreply@blogger.comtag:blogger.com,1999:blog-7735872642513631302.post-20597770390443080972013-10-03T06:46:08.808+01:002013-10-03T06:46:08.808+01:00Hi,
1. Max age cannot exceed 15 because it is a 4...Hi,<br /><br />1. Max age cannot exceed 15 because it is a 4 bit field (that may not be true for 64 bit JVM, not sure about it).<br />2. Provided max age is 15 - TenuringThreshold = 16 means keep object in young space until overflow.<br />3. JVM adjusts TenuringThreshold to prevent survival space overflow and usually it is far less than 16<br /><br />Regards,<br />AlexeyAlexey Ragozinhttps://www.blogger.com/profile/13720493857045012756noreply@blogger.comtag:blogger.com,1999:blog-7735872642513631302.post-58435516864256446772013-09-21T02:35:55.885+01:002013-09-21T02:35:55.885+01:00You said:
If object has survived certain number o...You said:<br /><br />If object has survived certain number of young space collections, it will be promoted to old space.<br /><br />However, according to my observation, objects won't be promoted until it hits the Desired survivor size limit.<br /><br />When I checked OpenJDK 7, I saw this:<br />http://hg.openjdk.java.net/jdk7/hotspot/hotspot/raw-file/92da084fefc9/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp<br /><br /> // Try allocating obj in to-space (unless too old)<br /> if (dummyOld.age() < tenuring_threshold()) {<br /> new_obj = (oop)par_scan_state->alloc_in_to_space(sz);<br /> if (new_obj == NULL) {<br /> set_survivor_overflow(true);<br /> }<br /> }<br /><br />In my test, tenuring_threshold is almost always 16, while the max age is 15, and since it had plenty of room in survivor space, allocation for new_obj succeeded most of the time. So I believe this is the place the GC will go:<br /><br /> } else {<br /> // Is in to-space; do copying ourselves.<br /> Copy::aligned_disjoint_words((HeapWord*)old, (HeapWord*)new_obj, sz);<br /> forward_ptr = old->forward_to_atomic(new_obj);<br /> // Restore the mark word copied above.<br /> new_obj->set_mark(m);<br /> // Increment age if obj still in new generation<br /> new_obj->incr_age();<br /> par_scan_state->age_table()->add(new_obj, sz);<br /> }<br /><br />For new_obj->set_mark(m), I guess this is the final code for execution:<br /><br />http://hg.openjdk.java.net/jdk7/hotspot/hotspot/file/9b0ca45cd756/src/share/vm/oops/markOop.hpp<br /><br />markOop incr_age() const { return age() == max_age ? markOop(this) : set_age(age() + 1); }<br /><br />So the age will stop growing when it reaches max_age.<br /><br />Without enough knowledge, I don't know how max_age is set. But I would like to guess that max_age was 15 in my test, so that all those objects will remain in survivor space for a very long time, say 3 hours or more.<br /><br />However, in my application, I really want those object promote to Old Gen. Keeping them in the Survivor space hurt the performance, because every minor GC needs to copy all those very old objects again and again, not sure about the scanning. <br /><br />I also read "OpenJDK patch cutting down GC pause duration up to 8 times". I am wondering whether this patch will help improving the performance for case like mine. I am using Oracle Java 7 up 09, not sure whether it contains you patch or not.<br /><br />Thank you very much for all of your effort.<br />Anonymoushttps://www.blogger.com/profile/10604466177025085730noreply@blogger.com