RFR: JDK-8133706: Kitchensink hanged

Jon Masamitsu jon.masamitsu at oracle.com
Mon Sep 21 18:08:34 UTC 2015


Bengt,

It's correct that if the else is taken

  178       } else {
  179         // We don't want to update the marking status if a GC pause
  180         // is already underway.
  181         SuspendibleThreadSetJoiner sts_join;
  182         g1h->collector_state()->set_mark_in_progress(false);
  183       }

then free_regions_coming() will always return false?
If yes, then the change looks good.

Also if you choose to move the block
of code (lines 185-214)

  185       // Check if cleanup set the free_regions_coming flag. If it
  186       // hasn't, we can just skip the next step.
  187       if (g1h->free_regions_coming()) {
...

  214       }

after

  177         VMThread::execute(&op);

I'll gladly code review the move of that code (but it is not
necessary).

Jon

On 09/19/2015 04:19 AM, Bengt Rutisson wrote:
>
> Hi everyone,
>
> Could I have a couple of reviews for this change?
>
> http://cr.openjdk.java.net/~brutisso/8133706/webrev.00/
> https://bugs.openjdk.java.net/browse/JDK-8133706
>
> The bug report contains some good analysis from Eric Caspole, David 
> Holmes and Yumin Qi.
>
> Thanks for this valuable investigation! Basically the problem is that 
> the heap regions that can be reclaimed by the cleanup phase are not 
> made available until they have been cleaned up in a concurrent phase. 
> If a GC happens while we are doing the concurrent cleaning up of the 
> free regions, the GC will wait for the concurrent cleaning to finish, 
> either by calling new_region_try_secondary_free_list() or 
> wait_while_free_regions_coming(). But since the logging before we 
> start the concurrent cleaning is now joining the STS, that cleaning is 
> getting blocked by the GC safepoint. So, we have a deadlock.
>
> This was actually documented in the ConcurrentMarkThread::run() 
> method, but I missed that when I added the cm_log() calls.
>
>         // Notify anyone who's waiting that there are no more free
>         // regions coming. We have to do this before we join the STS
>         // (in fact, we should not attempt to join the STS in the
>         // interval between finishing the cleanup pause and clearing
>         // the free_regions_coming flag) otherwise we might deadlock:
>         // a GC worker could be blocked waiting for the notification
>         // whereas this thread will be blocked for the pause to finish
>         // while it's trying to join the STS, which is conditional on
>         // the GC workers finishing.
>
>
> The simplest fix that I could come up with was to move the logging 
> from the  ConcurrentMarkThread::run() method in to the very end of the 
> stopped part of the cleanup phase. This ensures that we don’t mix the 
> log output with any logging that a GC does but id does not require 
> joining the STS since we are already at a safepoint.
>
> I left the timing (logged as part of the “GC concurrent-cleanup-end” 
> entry) unchanged. This means that there could be a slight mismatch 
> between the timestamps for “concurrent-cleanup-start” and 
> “concurrent-cleanup-end” and the time logged by 
> “concurrent-cleanup-end”. I hope the simplicity of the change 
> outweighs the disadvantage of this mismatch.
>
> Thanks,
> Bengt




More information about the hotspot-gc-dev mailing list