8138681: Runtime.getFreeMemory() reports wrong value after humongous allocation
Reviewed-by: tschatzl, mgerdin
This commit is contained in:
parent
57776e7af1
commit
2d7e74703d
@ -499,11 +499,14 @@ HeapWord* G1BlockOffsetArrayContigSpace::initialize_threshold() {
|
||||
return _next_offset_threshold;
|
||||
}
|
||||
|
||||
void G1BlockOffsetArrayContigSpace::set_for_starts_humongous(HeapWord* obj_top) {
|
||||
void G1BlockOffsetArrayContigSpace::set_for_starts_humongous(HeapWord* obj_top, size_t fill_size) {
|
||||
// The first BOT entry should have offset 0.
|
||||
reset_bot();
|
||||
alloc_block(_bottom, obj_top);
|
||||
}
|
||||
if (fill_size > 0) {
|
||||
alloc_block(obj_top, fill_size);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
void G1BlockOffsetArrayContigSpace::print_on(outputStream* out) {
|
||||
|
@ -372,7 +372,7 @@ class G1BlockOffsetArrayContigSpace: public G1BlockOffsetArray {
|
||||
HeapWord* block_start_unsafe(const void* addr);
|
||||
HeapWord* block_start_unsafe_const(const void* addr) const;
|
||||
|
||||
void set_for_starts_humongous(HeapWord* obj_top);
|
||||
void set_for_starts_humongous(HeapWord* obj_top, size_t fill_size);
|
||||
|
||||
virtual void print_on(outputStream* out) PRODUCT_RETURN;
|
||||
};
|
||||
|
@ -339,11 +339,18 @@ G1CollectedHeap::humongous_obj_allocate_initialize_regions(uint first,
|
||||
// thread to calculate the object size incorrectly.
|
||||
Copy::fill_to_words(new_obj, oopDesc::header_size(), 0);
|
||||
|
||||
size_t fill_size = word_size_sum - word_size;
|
||||
if (fill_size >= min_fill_size()) {
|
||||
fill_with_objects(obj_top, fill_size);
|
||||
} else {
|
||||
fill_size = 0;
|
||||
}
|
||||
|
||||
// We will set up the first region as "starts humongous". This
|
||||
// will also update the BOT covering all the regions to reflect
|
||||
// that there is a single object that starts at the bottom of the
|
||||
// first region.
|
||||
first_hr->set_starts_humongous(obj_top);
|
||||
first_hr->set_starts_humongous(obj_top, fill_size);
|
||||
first_hr->set_allocation_context(context);
|
||||
// Then, if there are any, we will set up the "continues
|
||||
// humongous" regions.
|
||||
@ -365,9 +372,9 @@ G1CollectedHeap::humongous_obj_allocate_initialize_regions(uint first,
|
||||
|
||||
// Now that the BOT and the object header have been initialized,
|
||||
// we can update top of the "starts humongous" region.
|
||||
first_hr->set_top(MIN2(first_hr->end(), obj_top));
|
||||
first_hr->set_top(first_hr->end());
|
||||
if (_hr_printer.is_active()) {
|
||||
_hr_printer.alloc(G1HRPrinter::StartsHumongous, first_hr, first_hr->top());
|
||||
_hr_printer.alloc(G1HRPrinter::StartsHumongous, first_hr, first_hr->end());
|
||||
}
|
||||
|
||||
// Now, we will update the top fields of the "continues humongous"
|
||||
@ -375,25 +382,18 @@ G1CollectedHeap::humongous_obj_allocate_initialize_regions(uint first,
|
||||
hr = NULL;
|
||||
for (uint i = first + 1; i < last; ++i) {
|
||||
hr = region_at(i);
|
||||
if ((i + 1) == last) {
|
||||
// last continues humongous region
|
||||
assert(hr->bottom() < obj_top && obj_top <= hr->end(),
|
||||
"new_top should fall on this region");
|
||||
hr->set_top(obj_top);
|
||||
_hr_printer.alloc(G1HRPrinter::ContinuesHumongous, hr, obj_top);
|
||||
} else {
|
||||
// not last one
|
||||
assert(obj_top > hr->end(), "obj_top should be above this region");
|
||||
hr->set_top(hr->end());
|
||||
hr->set_top(hr->end());
|
||||
if (_hr_printer.is_active()) {
|
||||
_hr_printer.alloc(G1HRPrinter::ContinuesHumongous, hr, hr->end());
|
||||
}
|
||||
}
|
||||
// If we have continues humongous regions (hr != NULL), its top should
|
||||
// match obj_top.
|
||||
assert(hr == NULL || (hr->top() == obj_top), "sanity");
|
||||
|
||||
assert(hr == NULL || (hr->bottom() < obj_top && obj_top <= hr->end()),
|
||||
"obj_top should be in last region");
|
||||
|
||||
check_bitmaps("Humongous Region Allocation", first_hr);
|
||||
|
||||
increase_used(word_size * HeapWordSize);
|
||||
increase_used(word_size_sum * HeapWordSize);
|
||||
|
||||
for (uint i = first; i < last; ++i) {
|
||||
_humongous_set.add(region_at(i));
|
||||
|
@ -211,14 +211,14 @@ void HeapRegion::calc_gc_efficiency() {
|
||||
_gc_efficiency = (double) reclaimable_bytes() / region_elapsed_time_ms;
|
||||
}
|
||||
|
||||
void HeapRegion::set_starts_humongous(HeapWord* obj_top) {
|
||||
void HeapRegion::set_starts_humongous(HeapWord* obj_top, size_t fill_size) {
|
||||
assert(!is_humongous(), "sanity / pre-condition");
|
||||
assert(top() == bottom(), "should be empty");
|
||||
|
||||
_type.set_starts_humongous();
|
||||
_humongous_start_region = this;
|
||||
|
||||
_offsets.set_for_starts_humongous(obj_top);
|
||||
_offsets.set_for_starts_humongous(obj_top, fill_size);
|
||||
}
|
||||
|
||||
void HeapRegion::set_continues_humongous(HeapRegion* first_hr) {
|
||||
@ -756,16 +756,6 @@ void HeapRegion::verify(VerifyOption vo,
|
||||
size_t obj_size = block_size(p);
|
||||
object_num += 1;
|
||||
|
||||
if (is_region_humongous != g1->is_humongous(obj_size) &&
|
||||
!g1->is_obj_dead(obj, this)) { // Dead objects may have bigger block_size since they span several objects.
|
||||
gclog_or_tty->print_cr("obj " PTR_FORMAT " is of %shumongous size ("
|
||||
SIZE_FORMAT " words) in a %shumongous region",
|
||||
p2i(p), g1->is_humongous(obj_size) ? "" : "non-",
|
||||
obj_size, is_region_humongous ? "" : "non-");
|
||||
*failures = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!g1->is_obj_dead_cond(obj, this, vo)) {
|
||||
if (obj->is_oop()) {
|
||||
Klass* klass = obj->klass();
|
||||
@ -876,14 +866,6 @@ void HeapRegion::verify(VerifyOption vo,
|
||||
}
|
||||
}
|
||||
|
||||
if (is_region_humongous && object_num > 1) {
|
||||
gclog_or_tty->print_cr("region [" PTR_FORMAT "," PTR_FORMAT "] is humongous "
|
||||
"but has " SIZE_FORMAT ", objects",
|
||||
p2i(bottom()), p2i(end()), object_num);
|
||||
*failures = true;
|
||||
return;
|
||||
}
|
||||
|
||||
verify_strong_code_roots(vo, failures);
|
||||
}
|
||||
|
||||
|
@ -455,9 +455,9 @@ class HeapRegion: public G1OffsetTableContigSpace {
|
||||
// the first region in a series of one or more contiguous regions
|
||||
// that will contain a single "humongous" object.
|
||||
//
|
||||
// obj_top : points to the end of the humongous object that's being
|
||||
// allocated.
|
||||
void set_starts_humongous(HeapWord* obj_top);
|
||||
// obj_top : points to the top of the humongous object.
|
||||
// fill_size : size of the filler object at the end of the region series.
|
||||
void set_starts_humongous(HeapWord* obj_top, size_t fill_size);
|
||||
|
||||
// Makes the current region be a "continues humongous'
|
||||
// region. first_hr is the "start humongous" region of the series
|
||||
|
Loading…
Reference in New Issue
Block a user