JDK-6974928 : G1: sometimes humongous objects are allocated in young regions
  • Type: Bug
  • Component: hotspot
  • Sub-Component: gc
  • Affected Version: hs19
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2010-08-05
  • Updated: 2013-09-18
  • Resolved: 2011-04-23
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7 Other
6u21pFixed 7Fixed hs19Fixed
Description
During testing some other changes, I came across a case where humongous objects were being allocated on young regions and copied during collection pauses. This breaks the fundamental G1 assumption that humongous objects are always allocated separately. I've only seen this when running dacapo pmd.

Comments
EVALUATION http://hg.openjdk.java.net/jdk7/hotspot-gc/hotspot/rev/bb847e31b836
17-08-2010

SUGGESTED FIX The fix is straightforward, in attempt_allocation() only attempt to allocate into the current alloc region if the allocation request is not humongous. If it is, we'll go to the attempt_allocation_slow() method which will allocate the humongous object correctly.
05-08-2010

EVALUATION The reason for this was that mem_allocate was being called directly from runtime / interpreter to allocate an array. mem_allocate in turn called attempt_allocation(): inline HeapWord* G1CollectedHeap::attempt_allocation(size_t word_size, bool permit_collection_pause) { ... if (_cur_alloc_region != NULL) { // If this allocation causes a region to become non empty, // then we need to update our free_regions count. res = _cur_alloc_region->allocate(word_size); } ... return attempt_allocation_slow(word_size, permit_collection_pause); } attempt_allocation() first tries to allocate the object in the current alloc region. If it happens that there's still space in that region (this can happen if the humongous object size is smaller than the region size and larger than the humongous size threshold, currently being region size / 2), the allocation would go ahead, even if the region is young.
05-08-2010