<div dir="ltr">Hi Jungwoo,<div><br></div><div>To my knowledge, the only way JNI synchronizes with GC in HotSpot is by the means of the GC locker and safepoint checks upon entry to VM.</div><div><br></div><div>When JNI code enters a critical section (e.g. after calling GetPrimitiveArrayCritical() but before calling ReleasePrimitiveArrayCritical()), HotSpot will activate the GC locker, meaning it does not allow a GC at the moment. If a GC is requested when the GC locker is active, HotSpot will try to expand the heap to fulfill the allocation request instead of doing a GC.</div>
<div>When JNI exits all critical sections, the GC locker is inactivated. If there had been a GC request when the GC locker was active, then a major GC will be started at GC locker inactivation time. -XX:+GCLockerInvokesConcurrent overrides that behavior to start a concurrent GC cycle instead of a full GC.</div>
<div><br></div><div>In the general case, JNI synchronizes with the GC by safepoints. When JNI calls into the VM (via JNI Invocation API) or returns to the VM, there are safepoint checks at the entry point, so that if a GC safepoint is active, it shouldn't run past the safepoint until GC completes. That's how the assert you mentioned could work.</div>
<div><br></div><div>BTW, Universe::heap()->is_gc_active() only checks if there's a stop-the-world GC activity happening right now. It doesn't care about the concurrent phases.<br></div><div><br></div><div>Hope it helps,</div>
<div>Kris</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Apr 2, 2014 at 2:00 PM, Jungwoo Ha <span dir="ltr"><<a href="mailto:jwha@google.com" target="_blank">jwha@google.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Is there a good write up on how the synchronization happen between JNI and GC?<div>I am looking at the NewGlobalRef code but it has assert statement like this:</div>
<div><br></div><div><span style="line-height:16.25px;font-size:medium;white-space:pre-wrap;font-family:monospace">assert(!Universe::heap()->is_gc_active(), </span><span style="color:rgb(0,136,0);font-family:monospace;font-size:medium;line-height:16.25px;white-space:pre-wrap">"can't extend the root set during GC"</span><span style="line-height:16.25px;font-size:medium;white-space:pre-wrap;font-family:monospace">);</span><br>
</div><div><span style="line-height:16.25px;font-size:medium;white-space:pre-wrap;font-family:monospace"><br></span></div>But how is this enforced by the JNI code calling NewGlobalRef?<div><br></div><div>Thanks,</div>
<div>Jungwoo</div></div>
</blockquote></div><br></div>