RFR: 8138920: Refactor the sampling thread from ConcurrentG1RefineThread

Derek White derek.white at oracle.com
Sat Oct 17 01:32:03 UTC 2015


3rd Webrev for review please:

This version does away with the common abstract base case 
ConcurrentServiceThread, and pushes the code down to the concrete 
classes. This may get cleaned up in a later fix to ConcurrentGCThread.


RFE: JDK-8138920 <https://bugs.openjdk.java.net/browse/JDK-8138920> 
Refactor the sampling thread from ConcurrentG1RefineThread

Webrev: http://cr.openjdk.java.net/~drwhite/8138920/webrev.03/

Passed jprt (finally!).

Thanks for looking!

  - Derek

On 10/9/15 12:01 PM, Bengt Rutisson wrote:
>
> Hi Derek,
>
> Comments inlined.
>
> On 2015-10-09 00:29, Derek White wrote:
>> Another call for review:
>>
>> 2nd webrev:
>> http://cr.openjdk.java.net/~drwhite/8138920/webrev.02/
>>
>> See changes and comments below:
>>
>> On 10/8/15 2:47 AM, Bengt Rutisson wrote:
>>>
>>> Hi Derek,
>>>
>>> On 2015-10-07 17:19, Derek White wrote:
>>>> Hi Bengt,
>>>>
>>>> On 10/7/15 4:02 AM, Bengt Rutisson wrote:
>>>>> Hi Derek,
>>>>>
>>>>> Thanks for fixing this!
>>>>>
>>>>> On 2015-10-06 19:51, Derek White wrote:
>>>>>> Refactor and cleanup the G1 concurrent thread classes:
>>>>>>  - Pull out a sampling thread class (now 
>>>>>> ConcurrentG1SampleThread) from ConcurrentG1RefineThread.
>>>>>>  - Factor out an abstract base class ConcurrentG1ServiceThread 
>>>>>> that is used by:
>>>>>>     - ConcurrentG1RefineThread
>>>>>>     - ConcurrentG1SampleThread
>>>>>>     - ConcurrentMarkThread
>>>>>>  - Made the handling of the "primary" refinement thread more 
>>>>>> explicit.
>>>>>>  - Updated obsolete and confusing comments
>>>>>>
>>>>>> This is tech debt that also will allow disabling concurrent 
>>>>>> refinement (if desired) and also fixes a P4 bug.
>>>>>> Patch started by Thomas and improved and/or mangled myself.
>>>>>>
>>>>>> RFE: JDK-8138920 
>>>>>> <https://bugs.openjdk.java.net/browse/JDK-8138920> Refactor the 
>>>>>> sampling thread from ConcurrentG1RefineThread
>>>>>>
>>>>>> Webrev: http://cr.openjdk.java.net/~drwhite/8138920/webrev.01/
>>>>>
>>>>> Overall this looks really good to me.
>>>>>
>>>>> Some comments:
>>>>>
>>>>> No one seems to depend on 
>>>>> ConcurrentG1ServiceThread::vtime_accum(). All uses have the 
>>>>> specific subclass available. So, I don't think the pure virtual 
>>>>> declaration in ConcurrentG1ServiceThread is needed. I'd just 
>>>>> remove that and also make the corresponding methods in the 
>>>>> subclasses non-virtual.
>>>>
>>>> OK. At some point we need to systematic rewrite of timing, but that 
>>>> can wait.
>>>
>>> Quite agree.
>>>
>>>>> That more or less only leaves the run() and stop() methods in 
>>>>> ConcurrentG1ServiceThread. It is kind of nice for the subclasses 
>>>>> to get help with this, but I wonder if it is not possible to 
>>>>> improve the ConcurrentGCThread class to help with this instead. 
>>>>> Basically I guess I am a little unsure if the extra class 
>>>>> ConcurrentG1ServiceThread is really needed.
>>>>>
>>>> I'll look at ConcurrentGCThread to see how well it could cover 
>>>> these cases.
>>>
>>> Thanks. I think it is worth a try. If it doesn't turn out well we 
>>> can keep the intermediate class, but I think it is worth exploring.
>>
>> I looked at pushing ConcurrentServiceThread up into 
>> ConcurrentGCThread, but things got a little complicated. 
>> ConcurrentG1RefineThread, ConcurrentMarkThread, and 
>> ConcurrentSampleThread have a very "regularized" implementation of 
>> the "termination protocol". G1StringDedupThread is slightly off from 
>> this, and ConcurrentMarkSweepThread more so.  Pushing the shared code 
>> up into ConcurrentGCThread but not using it in G1StringDedupThread 
>> and ConcurrentMarkSweepThread seems confusing.
>>
>> There's a tension between providing a framework that handles all 
>> shared factorizable code, but can become a straight jacket for future 
>> code, and everyone doing everything separately and differently. This 
>> webrev is somewhere in the middle. Some of the changes between 
>> webrev.01 and .02 are to make the duplicated code more similar, even 
>> though it's not shared.
>
> I see. Thanks for investigating it!
>
> I think I agree with Per, though. The value of ConcurrentServiceThread 
> in its current form is IMHO not really worth the extra complexity of 
> having it. I would prefer to just duplicate the code in 
> ConcurrentG1RefineThread, ConcurrentMarkThread, and 
> ConcurrentSampleThread for now and then have a separate change to try 
> to clean this part up.
>
>>
>>>>> Naming. The naming in G1 is a bit inconsistent. Some files and 
>>>>> classes are prefixed with G1 and some are not. But if they are 
>>>>> called something with G1 it is normally a prefix. So, I would 
>>>>> prefer the new classes to be called G1Concurrent* instead of 
>>>>> ConcurrentG1*.
>>>>
>>>> So we have:
>>>>     - ConcurrentG1RefineThread
>>>>     - ConcurrentMarkThread
>>>>
>>>> And I added:
>>>>     - ConcurrentG1SampleThread
>>>>     - ConcurrentG1ServiceThread
>>>>
>>>> And maybe I'm removing ConcurrentG1ServiceThread. In that case I'd 
>>>> be inclined to rename:
>>>>      ConcurrentG1SampleThread => ConcurrentSampleThread 
>>>
>>> Sounds good. The ConcurrentG1Refine* classes are really the only 
>>> oddly named G1 classes, so I think it is better not to let that 
>>> naming spread.
>> This version includes the class renaming. 
>
> Thanks for fixing this.
>
> If we do decide to keep ConcurrentServiceThread around I think it 
> would be better to move ConcurrentSampleThread into its own file. It 
> is a separate enough entity to warrant its own file I think.
>
>>>
>>>>> You write "and also fixes a P4 bug". Which bug is that?
>>>> JDK-8136856 <https://bugs.openjdk.java.net/browse/JDK-8136856> G1 
>>>> makes two concurrent refinement threads with 
>>>> -XX:G1ConcRefinementThreads=1
>>>> (because the sampling thread "is-a" concurrent refinement thread.
>>>
>>> Ah. I see. Makes sense. Thanks.
>>>
>>> But it is still not possible to turn refinement off by setting 
>>> -XX:G1ConcRefinementThreads=0 since that is considered the default, 
>>> right?
>>
>> I'm not sure about this. If I recall correctly, Thomas implied that 
>> it was hard to disable concurrent refinement without disabling the 
>> sampling thread too.
>
> I'm thinking about this code in Arguments::set_g1_gc_flags():
>
>   if (G1ConcRefinementThreads == 0) {
>     FLAG_SET_DEFAULT(G1ConcRefinementThreads, ParallelGCThreads);
>   }
>
> Could we change that, so that you could turn off refinement by setting 
> -XX:G1ConcRefinementThreads=0 ? It should probably be handled as a 
> separate fix though.
>
> Thanks,
> Bengt
>
>>
>>>> I cant' recall how to mark a bug as blocking another bug.
>>>
>>> You add a link (More->Link) to the other bug and choose "block" or 
>>> "is blocked by".
>>>
>>> Thanks,
>>> Bengt
>> Thanks for the tip!
>>
>> - Derek
>>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/hotspot-gc-dev/attachments/20151016/93427036/attachment.htm>


More information about the hotspot-gc-dev mailing list