Request for review: 8044406: JVM crash with JDK8 (build 1.8.0-b132) with G1 GC
Poonam Bajaj
poonam.bajaj at oracle.com
Mon Aug 18 11:08:24 UTC 2014
Hello Mikael,
Thanks for your review. Here's the updated webrev:
http://cr.openjdk.java.net/~poonam/8044406/webrev.01/
regards,
Poonam
On 8/18/2014 2:02 PM, Mikael Gerdin wrote:
> Hi Poonam,
>
> On 2014-08-17 02:54, Poonam Bajaj wrote:
>> Hi,
>>
>> Could I have reviews for the fix for a G1 GC crash:
>>
>> 8044406 <https://bugs.openjdk.java.net/browse/JDK-8044406>: JVM crash
>> with JDK8 (build 1.8.0-b132) with G1 GC
>> Webrev: http://cr.openjdk.java.net/~poonam/8044406/webrev.00/webrev/
>
> 7020 // Determine how far we are from the next card boundary. If
> it is smaller than
> 7021 // the minimum object size we can allocate into, expand into
> the next card.
> 7022 size_t top = cur->used();
> 7023 size_t aligned_top = align_size_up_(top,
> G1BlockOffsetSharedArray::N_bytes);
>
> It seems a bit odd to me to do this calculation on the sizes instead
> of the addresses in the region. Also, the naming is confusing since
> "top" almost always refers to the topmost allocated address in a
> particular memory range.
> Can you change the above to
> HeapWord* top = cur->top();
> HeapWord* aligned_top = align_ptr_up...
>
>
> 7024
> 7025 size_t to_allocate_words = (aligned_top - top) / HeapWordSize;
>
> The subtraction should be replaced by a call to pointer_delta if you
> change the types of top and aligned_top to pointers.
>
> 7026 if ((cur->top() + to_allocate_words) != cur->end() && // Not
> completely filled yet.
> 7027 (to_allocate_words != 0) && // Not at card boundary.
> 7028 (to_allocate_words <= CollectedHeap::min_fill_size())) {
> 7029 // Cannot fit any object into the area to the next card
> boundary. Simply create
> 7030 // an object that fits a single object.
> 7031 to_allocate_words += CollectedHeap::min_fill_size();
> 7032 }
>
> Generally, if you feel the need to explain each condition in a
> three-clause if statement then maybe it's a good idea to rephrase it
> in some way. Maybe use a MAX2-expression to get above the minimum
> object size and move the "to_allocate_words != 0" check to encompass
> the entire filling logic?
>
> 7033
> 7034 if (to_allocate_words != 0) {
> 7035 HeapWord* dummy =
> G1AllocRegion::attempt_allocation(to_allocate_words, true /*
> bot_updates */);
>
> You don't need the G1AllocRegion scope prefix here, attempt_allocation
> is in the current scope.
>
> 7036 CollectedHeap::fill_with_object(dummy, to_allocate_words);
> 7037 }
>
> /Mikael
>
>>
>> The crash happens with the following stack trace:
>> Stack: [0x00007fd435a1f000,0x00007fd435b20000], sp=0x00007fd435b1bc30,
>> free space=1011k
>> Native frames: (J=compiled Java code, j=interpreted, Vv=VM code,
>> C=native code)
>> V [libjvm.so+0x541261]
>> G1BlockOffsetArray::forward_to_block_containing_addr_slow(HeapWord*,
>> HeapWord*, void const*)+0xf1
>> V [libjvm.so+0x959e54]
>> DirtyCardToOopClosure::do_MemRegion(MemRegion)+0x64
>> V [libjvm.so+0x56d2a4] ScanRSClosure::doHeapRegion(HeapRegion*)+0x374
>> V [libjvm.so+0x542dd0]
>> G1CollectedHeap::collection_set_iterate_from(HeapRegion*,
>> HeapRegionClosure*)+0x60
>> V [libjvm.so+0x56c08c] G1RemSet::scanRS(OopsInHeapRegionClosure*,
>> CodeBlobToOopClosure*, int)+0xdc
>> V [libjvm.so+0x56c4d5]
>> G1RemSet::oops_into_collection_set_do(OopsInHeapRegionClosure*,
>> CodeBlobToOopClosure*, int)+0x145
>> V [libjvm.so+0x549ef4] G1CollectedHeap::g1_process_strong_roots(bool,
>> SharedHeap::ScanningOption, OopClosure*, OopsInHeapRegionClosure*,
>> G1KlassScanClosure*, int)+0x224
>> V [libjvm.so+0x558a88] G1ParTask::work(unsigned int)+0xb88
>> V [libjvm.so+0xa4a9ff] GangWorker::loop()+0xcf
>> V [libjvm.so+0x8a0058] java_start(Thread*)+0x108
>>
>> Here, the GC thread crashes while scanning the RemSet (part of the
>> non-CSet regions). And it happens to scan a region to which another
>> thread in G1ParEvacuateFollowersClosure is copying contents to, and this
>> region was found out to be an Old GC alloc region.
>>
>> This change makes sure that we fill up the last card of the Old GC alloc
>> region that was being allocated into, with a dummy object so that it
>> does not get scanned by the remset scanning GC threads.
>>
>> This change applies cleanly to 8u and 7u repos.
>>
>> Thanks to Thomas Schatzl for his help in investigating the crash and
>> suggesting this solution.
>>
>> Testing:
>> - JPRT
>> - Testing by Coherence QA
>>
>> Thanks,
>> Poonam
>>
More information about the hotspot-gc-dev
mailing list