8145092: Use Unified Logging for the GC logging

JEP-271. VM changes contributed by brutisso, test changes contributed by david.

Co-authored-by: David Lindholm <david.lindholm@oralce.com>
Reviewed-by: sjohanss, david, brutisso
This commit is contained in:
Bengt Rutisson 2015-12-10 14:57:55 +01:00
parent 581eb19018
commit ffeb0bdad0
200 changed files with 3331 additions and 6147 deletions

View file

@ -5719,7 +5719,7 @@ char* os::build_agent_function_name(const char *sym_name, const char *lib_name,
void TestReserveMemorySpecial_test() { void TestReserveMemorySpecial_test() {
if (!UseLargePages) { if (!UseLargePages) {
if (VerboseInternalVMTests) { if (VerboseInternalVMTests) {
gclog_or_tty->print("Skipping test because large pages are disabled"); tty->print("Skipping test because large pages are disabled");
} }
return; return;
} }
@ -5735,7 +5735,7 @@ void TestReserveMemorySpecial_test() {
char* result = os::reserve_memory_special(large_allocation_size, os::large_page_size(), NULL, false); char* result = os::reserve_memory_special(large_allocation_size, os::large_page_size(), NULL, false);
if (result == NULL) { if (result == NULL) {
if (VerboseInternalVMTests) { if (VerboseInternalVMTests) {
gclog_or_tty->print("Failed to allocate control block with size " SIZE_FORMAT ". Skipping remainder of test.", tty->print("Failed to allocate control block with size " SIZE_FORMAT ". Skipping remainder of test.",
large_allocation_size); large_allocation_size);
} }
} else { } else {
@ -5748,7 +5748,7 @@ void TestReserveMemorySpecial_test() {
char* actual_location = os::reserve_memory_special(expected_allocation_size, os::large_page_size(), expected_location, false); char* actual_location = os::reserve_memory_special(expected_allocation_size, os::large_page_size(), expected_location, false);
if (actual_location == NULL) { if (actual_location == NULL) {
if (VerboseInternalVMTests) { if (VerboseInternalVMTests) {
gclog_or_tty->print("Failed to allocate any memory at " PTR_FORMAT " size " SIZE_FORMAT ". Skipping remainder of test.", tty->print("Failed to allocate any memory at " PTR_FORMAT " size " SIZE_FORMAT ". Skipping remainder of test.",
expected_location, large_allocation_size); expected_location, large_allocation_size);
} }
} else { } else {

View file

@ -8,7 +8,6 @@
prepend in front of bootstrap class path prepend in front of bootstrap class path
-Xnoclassgc disable class garbage collection -Xnoclassgc disable class garbage collection
-Xlog:<opts> control JVM logging, use -Xlog:help for details -Xlog:<opts> control JVM logging, use -Xlog:help for details
-Xloggc:<file> log GC status to a file with time stamps
-Xbatch disable background compilation -Xbatch disable background compilation
-Xms<size> set initial Java heap size -Xms<size> set initial Java heap size
-Xmx<size> set maximum Java heap size -Xmx<size> set maximum Java heap size

View file

@ -26,6 +26,7 @@
#define SHARE_VM_GC_CMS_ALLOCATIONSTATS_HPP #define SHARE_VM_GC_CMS_ALLOCATIONSTATS_HPP
#include "gc/shared/gcUtil.hpp" #include "gc/shared/gcUtil.hpp"
#include "logging/log.hpp"
#include "memory/allocation.hpp" #include "memory/allocation.hpp"
#include "utilities/globalDefinitions.hpp" #include "utilities/globalDefinitions.hpp"
#include "utilities/macros.hpp" #include "utilities/macros.hpp"
@ -119,11 +120,9 @@ class AllocationStats VALUE_OBJ_CLASS_SPEC {
ssize_t old_desired = _desired; ssize_t old_desired = _desired;
float delta_ise = (CMSExtrapolateSweep ? intra_sweep_estimate : 0.0); float delta_ise = (CMSExtrapolateSweep ? intra_sweep_estimate : 0.0);
_desired = (ssize_t)(new_rate * (inter_sweep_estimate + delta_ise)); _desired = (ssize_t)(new_rate * (inter_sweep_estimate + delta_ise));
if (PrintFLSStatistics > 1) { log_trace(gc, freelist)("demand: " SSIZE_FORMAT ", old_rate: %f, current_rate: %f, "
gclog_or_tty->print_cr("demand: " SSIZE_FORMAT ", old_rate: %f, current_rate: %f, " "new_rate: %f, old_desired: " SSIZE_FORMAT ", new_desired: " SSIZE_FORMAT,
"new_rate: %f, old_desired: " SSIZE_FORMAT ", new_desired: " SSIZE_FORMAT, demand, old_rate, rate, new_rate, old_desired, _desired);
demand, old_rate, rate, new_rate, old_desired, _desired);
}
} }
} }

View file

@ -400,17 +400,16 @@ void CompactibleFreeListSpace::print_on(outputStream* st) const {
void CompactibleFreeListSpace::print_indexed_free_lists(outputStream* st) void CompactibleFreeListSpace::print_indexed_free_lists(outputStream* st)
const { const {
reportIndexedFreeListStatistics(); reportIndexedFreeListStatistics(st);
gclog_or_tty->print_cr("Layout of Indexed Freelists"); st->print_cr("Layout of Indexed Freelists");
gclog_or_tty->print_cr("---------------------------"); st->print_cr("---------------------------");
AdaptiveFreeList<FreeChunk>::print_labels_on(st, "size"); AdaptiveFreeList<FreeChunk>::print_labels_on(st, "size");
for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
_indexedFreeList[i].print_on(gclog_or_tty); _indexedFreeList[i].print_on(st);
for (FreeChunk* fc = _indexedFreeList[i].head(); fc != NULL; for (FreeChunk* fc = _indexedFreeList[i].head(); fc != NULL; fc = fc->next()) {
fc = fc->next()) { st->print_cr("\t[" PTR_FORMAT "," PTR_FORMAT ") %s",
gclog_or_tty->print_cr("\t[" PTR_FORMAT "," PTR_FORMAT ") %s", p2i(fc), p2i((HeapWord*)fc + i),
p2i(fc), p2i((HeapWord*)fc + i), fc->cantCoalesce() ? "\t CC" : "");
fc->cantCoalesce() ? "\t CC" : "");
} }
} }
} }
@ -422,7 +421,7 @@ const {
void CompactibleFreeListSpace::print_dictionary_free_lists(outputStream* st) void CompactibleFreeListSpace::print_dictionary_free_lists(outputStream* st)
const { const {
_dictionary->report_statistics(); _dictionary->report_statistics(st);
st->print_cr("Layout of Freelists in Tree"); st->print_cr("Layout of Freelists in Tree");
st->print_cr("---------------------------"); st->print_cr("---------------------------");
_dictionary->print_free_lists(st); _dictionary->print_free_lists(st);
@ -472,54 +471,58 @@ size_t BlkPrintingClosure::do_blk(HeapWord* addr) {
return sz; return sz;
} }
void CompactibleFreeListSpace::dump_at_safepoint_with_locks(CMSCollector* c, void CompactibleFreeListSpace::dump_at_safepoint_with_locks(CMSCollector* c, outputStream* st) {
outputStream* st) { st->print_cr("=========================");
st->print_cr("\n=========================");
st->print_cr("Block layout in CMS Heap:"); st->print_cr("Block layout in CMS Heap:");
st->print_cr("========================="); st->print_cr("=========================");
BlkPrintingClosure bpcl(c, this, c->markBitMap(), st); BlkPrintingClosure bpcl(c, this, c->markBitMap(), st);
blk_iterate(&bpcl); blk_iterate(&bpcl);
st->print_cr("\n======================================="); st->print_cr("=======================================");
st->print_cr("Order & Layout of Promotion Info Blocks"); st->print_cr("Order & Layout of Promotion Info Blocks");
st->print_cr("======================================="); st->print_cr("=======================================");
print_promo_info_blocks(st); print_promo_info_blocks(st);
st->print_cr("\n==========================="); st->print_cr("===========================");
st->print_cr("Order of Indexed Free Lists"); st->print_cr("Order of Indexed Free Lists");
st->print_cr("========================="); st->print_cr("=========================");
print_indexed_free_lists(st); print_indexed_free_lists(st);
st->print_cr("\n================================="); st->print_cr("=================================");
st->print_cr("Order of Free Lists in Dictionary"); st->print_cr("Order of Free Lists in Dictionary");
st->print_cr("================================="); st->print_cr("=================================");
print_dictionary_free_lists(st); print_dictionary_free_lists(st);
} }
void CompactibleFreeListSpace::reportFreeListStatistics() const { void CompactibleFreeListSpace::reportFreeListStatistics(const char* title) const {
assert_lock_strong(&_freelistLock); assert_lock_strong(&_freelistLock);
assert(PrintFLSStatistics != 0, "Reporting error"); LogHandle(gc, freelist, stats) log;
_dictionary->report_statistics(); if (!log.is_debug()) {
if (PrintFLSStatistics > 1) { return;
reportIndexedFreeListStatistics(); }
log.debug("%s", title);
_dictionary->report_statistics(log.debug_stream());
if (log.is_trace()) {
ResourceMark rm;
reportIndexedFreeListStatistics(log.trace_stream());
size_t total_size = totalSizeInIndexedFreeLists() + size_t total_size = totalSizeInIndexedFreeLists() +
_dictionary->total_chunk_size(DEBUG_ONLY(freelistLock())); _dictionary->total_chunk_size(DEBUG_ONLY(freelistLock()));
gclog_or_tty->print(" free=" SIZE_FORMAT " frag=%1.4f\n", total_size, flsFrag()); log.trace(" free=" SIZE_FORMAT " frag=%1.4f", total_size, flsFrag());
} }
} }
void CompactibleFreeListSpace::reportIndexedFreeListStatistics() const { void CompactibleFreeListSpace::reportIndexedFreeListStatistics(outputStream* st) const {
assert_lock_strong(&_freelistLock); assert_lock_strong(&_freelistLock);
gclog_or_tty->print("Statistics for IndexedFreeLists:\n" st->print_cr("Statistics for IndexedFreeLists:");
"--------------------------------\n"); st->print_cr("--------------------------------");
size_t total_size = totalSizeInIndexedFreeLists(); size_t total_size = totalSizeInIndexedFreeLists();
size_t free_blocks = numFreeBlocksInIndexedFreeLists(); size_t free_blocks = numFreeBlocksInIndexedFreeLists();
gclog_or_tty->print("Total Free Space: " SIZE_FORMAT "\n", total_size); st->print_cr("Total Free Space: " SIZE_FORMAT, total_size);
gclog_or_tty->print("Max Chunk Size: " SIZE_FORMAT "\n", maxChunkSizeInIndexedFreeLists()); st->print_cr("Max Chunk Size: " SIZE_FORMAT, maxChunkSizeInIndexedFreeLists());
gclog_or_tty->print("Number of Blocks: " SIZE_FORMAT "\n", free_blocks); st->print_cr("Number of Blocks: " SIZE_FORMAT, free_blocks);
if (free_blocks != 0) { if (free_blocks != 0) {
gclog_or_tty->print("Av. Block Size: " SIZE_FORMAT "\n", total_size/free_blocks); st->print_cr("Av. Block Size: " SIZE_FORMAT, total_size/free_blocks);
} }
} }
@ -1824,10 +1827,7 @@ CompactibleFreeListSpace::sweep_completed() {
void void
CompactibleFreeListSpace::gc_prologue() { CompactibleFreeListSpace::gc_prologue() {
assert_locked(); assert_locked();
if (PrintFLSStatistics != 0) { reportFreeListStatistics("Before GC:");
gclog_or_tty->print("Before GC:\n");
reportFreeListStatistics();
}
refillLinearAllocBlocksIfNeeded(); refillLinearAllocBlocksIfNeeded();
} }
@ -1837,11 +1837,7 @@ CompactibleFreeListSpace::gc_epilogue() {
assert(_promoInfo.noPromotions(), "_promoInfo inconsistency"); assert(_promoInfo.noPromotions(), "_promoInfo inconsistency");
_promoInfo.stopTrackingPromotions(); _promoInfo.stopTrackingPromotions();
repairLinearAllocationBlocks(); repairLinearAllocationBlocks();
// Print Space's stats reportFreeListStatistics("After GC:");
if (PrintFLSStatistics != 0) {
gclog_or_tty->print("After GC:\n");
reportFreeListStatistics();
}
} }
// Iteration support, mostly delegated from a CMS generation // Iteration support, mostly delegated from a CMS generation
@ -2014,9 +2010,7 @@ void CompactibleFreeListSpace::beginSweepFLCensus(
size_t i; size_t i;
for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
AdaptiveFreeList<FreeChunk>* fl = &_indexedFreeList[i]; AdaptiveFreeList<FreeChunk>* fl = &_indexedFreeList[i];
if (PrintFLSStatistics > 1) { log_trace(gc, freelist)("size[" SIZE_FORMAT "] : ", i);
gclog_or_tty->print("size[" SIZE_FORMAT "] : ", i);
}
fl->compute_desired(inter_sweep_current, inter_sweep_estimate, intra_sweep_estimate); fl->compute_desired(inter_sweep_current, inter_sweep_estimate, intra_sweep_estimate);
fl->set_coal_desired((ssize_t)((double)fl->desired() * CMSSmallCoalSurplusPercent)); fl->set_coal_desired((ssize_t)((double)fl->desired() * CMSSmallCoalSurplusPercent));
fl->set_before_sweep(fl->count()); fl->set_before_sweep(fl->count());
@ -2065,16 +2059,10 @@ void CompactibleFreeListSpace::clearFLCensus() {
} }
void CompactibleFreeListSpace::endSweepFLCensus(size_t sweep_count) { void CompactibleFreeListSpace::endSweepFLCensus(size_t sweep_count) {
if (PrintFLSStatistics > 0) { log_debug(gc, freelist)("CMS: Large block " PTR_FORMAT, p2i(dictionary()->find_largest_dict()));
HeapWord* largestAddr = (HeapWord*) dictionary()->find_largest_dict();
gclog_or_tty->print_cr("CMS: Large block " PTR_FORMAT,
p2i(largestAddr));
}
setFLSurplus(); setFLSurplus();
setFLHints(); setFLHints();
if (PrintGC && PrintFLSCensus > 0) { printFLCensus(sweep_count);
printFLCensus(sweep_count);
}
clearFLCensus(); clearFLCensus();
assert_locked(); assert_locked();
_dictionary->end_sweep_dict_census(CMSLargeSplitSurplusPercent); _dictionary->end_sweep_dict_census(CMSLargeSplitSurplusPercent);
@ -2213,14 +2201,15 @@ class VerifyAllBlksClosure: public BlkClosure {
} }
} }
if (res == 0) { if (res == 0) {
gclog_or_tty->print_cr("Livelock: no rank reduction!"); LogHandle(gc, verify) log;
gclog_or_tty->print_cr( log.info("Livelock: no rank reduction!");
" Current: addr = " PTR_FORMAT ", size = " SIZE_FORMAT ", obj = %s, live = %s \n" log.info(" Current: addr = " PTR_FORMAT ", size = " SIZE_FORMAT ", obj = %s, live = %s \n"
" Previous: addr = " PTR_FORMAT ", size = " SIZE_FORMAT ", obj = %s, live = %s \n", " Previous: addr = " PTR_FORMAT ", size = " SIZE_FORMAT ", obj = %s, live = %s \n",
p2i(addr), res, was_obj ?"true":"false", was_live ?"true":"false", p2i(addr), res, was_obj ?"true":"false", was_live ?"true":"false",
p2i(_last_addr), _last_size, _last_was_obj?"true":"false", _last_was_live?"true":"false"); p2i(_last_addr), _last_size, _last_was_obj?"true":"false", _last_was_live?"true":"false");
_sp->print_on(gclog_or_tty); ResourceMark rm;
guarantee(false, "Seppuku!"); _sp->print_on(log.info_stream());
guarantee(false, "Verification failed.");
} }
_last_addr = addr; _last_addr = addr;
_last_size = res; _last_size = res;
@ -2386,17 +2375,23 @@ void CompactibleFreeListSpace::check_free_list_consistency() const {
void CompactibleFreeListSpace::printFLCensus(size_t sweep_count) const { void CompactibleFreeListSpace::printFLCensus(size_t sweep_count) const {
assert_lock_strong(&_freelistLock); assert_lock_strong(&_freelistLock);
LogHandle(gc, freelist, census) log;
if (!log.is_debug()) {
return;
}
AdaptiveFreeList<FreeChunk> total; AdaptiveFreeList<FreeChunk> total;
gclog_or_tty->print("end sweep# " SIZE_FORMAT "\n", sweep_count); log.debug("end sweep# " SIZE_FORMAT, sweep_count);
AdaptiveFreeList<FreeChunk>::print_labels_on(gclog_or_tty, "size"); ResourceMark rm;
outputStream* out = log.debug_stream();
AdaptiveFreeList<FreeChunk>::print_labels_on(out, "size");
size_t total_free = 0; size_t total_free = 0;
for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
const AdaptiveFreeList<FreeChunk> *fl = &_indexedFreeList[i]; const AdaptiveFreeList<FreeChunk> *fl = &_indexedFreeList[i];
total_free += fl->count() * fl->size(); total_free += fl->count() * fl->size();
if (i % (40*IndexSetStride) == 0) { if (i % (40*IndexSetStride) == 0) {
AdaptiveFreeList<FreeChunk>::print_labels_on(gclog_or_tty, "size"); AdaptiveFreeList<FreeChunk>::print_labels_on(out, "size");
} }
fl->print_on(gclog_or_tty); fl->print_on(out);
total.set_bfr_surp( total.bfr_surp() + fl->bfr_surp() ); total.set_bfr_surp( total.bfr_surp() + fl->bfr_surp() );
total.set_surplus( total.surplus() + fl->surplus() ); total.set_surplus( total.surplus() + fl->surplus() );
total.set_desired( total.desired() + fl->desired() ); total.set_desired( total.desired() + fl->desired() );
@ -2408,14 +2403,13 @@ void CompactibleFreeListSpace::printFLCensus(size_t sweep_count) const {
total.set_split_births(total.split_births() + fl->split_births()); total.set_split_births(total.split_births() + fl->split_births());
total.set_split_deaths(total.split_deaths() + fl->split_deaths()); total.set_split_deaths(total.split_deaths() + fl->split_deaths());
} }
total.print_on(gclog_or_tty, "TOTAL"); total.print_on(out, "TOTAL");
gclog_or_tty->print_cr("Total free in indexed lists " log.debug("Total free in indexed lists " SIZE_FORMAT " words", total_free);
SIZE_FORMAT " words", total_free); log.debug("growth: %8.5f deficit: %8.5f",
gclog_or_tty->print("growth: %8.5f deficit: %8.5f\n", (double)(total.split_births()+total.coal_births()-total.split_deaths()-total.coal_deaths())/
(double)(total.split_births()+total.coal_births()-total.split_deaths()-total.coal_deaths())/ (total.prev_sweep() != 0 ? (double)total.prev_sweep() : 1.0),
(total.prev_sweep() != 0 ? (double)total.prev_sweep() : 1.0), (double)(total.desired() - total.count())/(total.desired() != 0 ? (double)total.desired() : 1.0));
(double)(total.desired() - total.count())/(total.desired() != 0 ? (double)total.desired() : 1.0)); _dictionary->print_dict_census(out);
_dictionary->print_dict_census();
} }
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
@ -2544,10 +2538,7 @@ void CFLS_LAB::compute_desired_plab_size() {
// Reset counters for next round // Reset counters for next round
_global_num_workers[i] = 0; _global_num_workers[i] = 0;
_global_num_blocks[i] = 0; _global_num_blocks[i] = 0;
if (PrintOldPLAB) { log_trace(gc, plab)("[" SIZE_FORMAT "]: " SIZE_FORMAT, i, (size_t)_blocks_to_claim[i].average());
gclog_or_tty->print_cr("[" SIZE_FORMAT "]: " SIZE_FORMAT,
i, (size_t)_blocks_to_claim[i].average());
}
} }
} }
} }
@ -2584,10 +2575,8 @@ void CFLS_LAB::retire(int tid) {
_indexedFreeList[i].set_size(i); _indexedFreeList[i].set_size(i);
} }
} }
if (PrintOldPLAB) { log_trace(gc, plab)("%d[" SIZE_FORMAT "]: " SIZE_FORMAT "/" SIZE_FORMAT "/" SIZE_FORMAT,
gclog_or_tty->print_cr("%d[" SIZE_FORMAT "]: " SIZE_FORMAT "/" SIZE_FORMAT "/" SIZE_FORMAT, tid, i, num_retire, _num_blocks[i], (size_t)_blocks_to_claim[i].average());
tid, i, num_retire, _num_blocks[i], (size_t)_blocks_to_claim[i].average());
}
// Reset stats for next round // Reset stats for next round
_num_blocks[i] = 0; _num_blocks[i] = 0;
} }

View file

@ -29,6 +29,7 @@
#include "gc/cms/promotionInfo.hpp" #include "gc/cms/promotionInfo.hpp"
#include "gc/shared/blockOffsetTable.hpp" #include "gc/shared/blockOffsetTable.hpp"
#include "gc/shared/space.hpp" #include "gc/shared/space.hpp"
#include "logging/log.hpp"
#include "memory/binaryTreeDictionary.hpp" #include "memory/binaryTreeDictionary.hpp"
#include "memory/freeList.hpp" #include "memory/freeList.hpp"
@ -275,8 +276,8 @@ class CompactibleFreeListSpace: public CompactibleSpace {
void verify_objects_initialized() const; void verify_objects_initialized() const;
// Statistics reporting helper functions // Statistics reporting helper functions
void reportFreeListStatistics() const; void reportFreeListStatistics(const char* title) const;
void reportIndexedFreeListStatistics() const; void reportIndexedFreeListStatistics(outputStream* st) const;
size_t maxChunkSizeInIndexedFreeLists() const; size_t maxChunkSizeInIndexedFreeLists() const;
size_t numFreeBlocksInIndexedFreeLists() const; size_t numFreeBlocksInIndexedFreeLists() const;
// Accessor // Accessor
@ -450,11 +451,9 @@ class CompactibleFreeListSpace: public CompactibleSpace {
void save_sweep_limit() { void save_sweep_limit() {
_sweep_limit = BlockOffsetArrayUseUnallocatedBlock ? _sweep_limit = BlockOffsetArrayUseUnallocatedBlock ?
unallocated_block() : end(); unallocated_block() : end();
if (CMSTraceSweeper) { log_develop_trace(gc, sweep)(">>>>> Saving sweep limit " PTR_FORMAT
gclog_or_tty->print_cr(">>>>> Saving sweep limit " PTR_FORMAT " for space [" PTR_FORMAT "," PTR_FORMAT ") <<<<<<",
" for space [" PTR_FORMAT "," PTR_FORMAT ") <<<<<<", p2i(_sweep_limit), p2i(bottom()), p2i(end()));
p2i(_sweep_limit), p2i(bottom()), p2i(end()));
}
} }
NOT_PRODUCT( NOT_PRODUCT(
void clear_sweep_limit() { _sweep_limit = NULL; } void clear_sweep_limit() { _sweep_limit = NULL; }

File diff suppressed because it is too large Load diff

View file

@ -35,6 +35,7 @@
#include "gc/shared/generationCounters.hpp" #include "gc/shared/generationCounters.hpp"
#include "gc/shared/space.hpp" #include "gc/shared/space.hpp"
#include "gc/shared/taskqueue.hpp" #include "gc/shared/taskqueue.hpp"
#include "logging/log.hpp"
#include "memory/freeBlockDictionary.hpp" #include "memory/freeBlockDictionary.hpp"
#include "memory/iterator.hpp" #include "memory/iterator.hpp"
#include "memory/virtualspace.hpp" #include "memory/virtualspace.hpp"
@ -308,9 +309,8 @@ class ChunkArray: public CHeapObj<mtGC> {
void reset() { void reset() {
_index = 0; _index = 0;
if (_overflows > 0 && PrintCMSStatistics > 1) { if (_overflows > 0) {
warning("CMS: ChunkArray[" SIZE_FORMAT "] overflowed " SIZE_FORMAT " times", log_trace(gc)("CMS: ChunkArray[" SIZE_FORMAT "] overflowed " SIZE_FORMAT " times", _capacity, _overflows);
_capacity, _overflows);
} }
_overflows = 0; _overflows = 0;
} }
@ -451,7 +451,7 @@ class CMSStats VALUE_OBJ_CLASS_SPEC {
// Debugging. // Debugging.
void print_on(outputStream* st) const PRODUCT_RETURN; void print_on(outputStream* st) const PRODUCT_RETURN;
void print() const { print_on(gclog_or_tty); } void print() const { print_on(tty); }
}; };
// A closure related to weak references processing which // A closure related to weak references processing which
@ -935,7 +935,7 @@ class CMSCollector: public CHeapObj<mtGC> {
void startTimer() { assert(!_timer.is_active(), "Error"); _timer.start(); } void startTimer() { assert(!_timer.is_active(), "Error"); _timer.start(); }
void stopTimer() { assert( _timer.is_active(), "Error"); _timer.stop(); } void stopTimer() { assert( _timer.is_active(), "Error"); _timer.stop(); }
void resetTimer() { assert(!_timer.is_active(), "Error"); _timer.reset(); } void resetTimer() { assert(!_timer.is_active(), "Error"); _timer.reset(); }
double timerValue() { assert(!_timer.is_active(), "Error"); return _timer.seconds(); } jlong timerTicks() { assert(!_timer.is_active(), "Error"); return _timer.ticks(); }
int yields() { return _numYields; } int yields() { return _numYields; }
void resetYields() { _numYields = 0; } void resetYields() { _numYields = 0; }
@ -961,7 +961,7 @@ class CMSCollector: public CHeapObj<mtGC> {
// Debugging // Debugging
void verify(); void verify();
bool verify_after_remark(bool silent = VerifySilently); bool verify_after_remark();
void verify_ok_to_terminate() const PRODUCT_RETURN; void verify_ok_to_terminate() const PRODUCT_RETURN;
void verify_work_stacks_empty() const PRODUCT_RETURN; void verify_work_stacks_empty() const PRODUCT_RETURN;
void verify_overflow_empty() const PRODUCT_RETURN; void verify_overflow_empty() const PRODUCT_RETURN;
@ -1234,7 +1234,6 @@ class ConcurrentMarkSweepGeneration: public CardGeneration {
const char* name() const; const char* name() const;
virtual const char* short_name() const { return "CMS"; } virtual const char* short_name() const { return "CMS"; }
void print() const; void print() const;
void printOccupancy(const char* s);
// Resize the generation after a compacting GC. The // Resize the generation after a compacting GC. The
// generation can be treated as a contiguous space // generation can be treated as a contiguous space

View file

@ -34,7 +34,7 @@
#include "gc/shared/gcHeapSummary.hpp" #include "gc/shared/gcHeapSummary.hpp"
#include "gc/shared/gcTimer.hpp" #include "gc/shared/gcTimer.hpp"
#include "gc/shared/gcTrace.hpp" #include "gc/shared/gcTrace.hpp"
#include "gc/shared/gcTraceTime.hpp" #include "gc/shared/gcTraceTime.inline.hpp"
#include "gc/shared/genCollectedHeap.hpp" #include "gc/shared/genCollectedHeap.hpp"
#include "gc/shared/genOopClosures.inline.hpp" #include "gc/shared/genOopClosures.inline.hpp"
#include "gc/shared/generation.hpp" #include "gc/shared/generation.hpp"
@ -45,6 +45,7 @@
#include "gc/shared/strongRootsScope.hpp" #include "gc/shared/strongRootsScope.hpp"
#include "gc/shared/taskqueue.inline.hpp" #include "gc/shared/taskqueue.inline.hpp"
#include "gc/shared/workgroup.hpp" #include "gc/shared/workgroup.hpp"
#include "logging/log.hpp"
#include "memory/resourceArea.hpp" #include "memory/resourceArea.hpp"
#include "oops/objArrayOop.hpp" #include "oops/objArrayOop.hpp"
#include "oops/oop.inline.hpp" #include "oops/oop.inline.hpp"
@ -270,9 +271,9 @@ void ParScanThreadState::undo_alloc_in_to_space(HeapWord* obj, size_t word_sz) {
} }
void ParScanThreadState::print_promotion_failure_size() { void ParScanThreadState::print_promotion_failure_size() {
if (_promotion_failed_info.has_failed() && PrintPromotionFailure) { if (_promotion_failed_info.has_failed()) {
gclog_or_tty->print(" (%d: promotion failure size = " SIZE_FORMAT ") ", log_trace(gc, promotion)(" (%d: promotion failure size = " SIZE_FORMAT ") ",
_thread_num, _promotion_failed_info.first_size()); _thread_num, _promotion_failed_info.first_size());
} }
} }
@ -298,11 +299,11 @@ public:
#if TASKQUEUE_STATS #if TASKQUEUE_STATS
static void static void
print_termination_stats_hdr(outputStream* const st = gclog_or_tty); print_termination_stats_hdr(outputStream* const st);
void print_termination_stats(outputStream* const st = gclog_or_tty); void print_termination_stats();
static void static void
print_taskqueue_stats_hdr(outputStream* const st = gclog_or_tty); print_taskqueue_stats_hdr(outputStream* const st);
void print_taskqueue_stats(outputStream* const st = gclog_or_tty); void print_taskqueue_stats();
void reset_stats(); void reset_stats();
#endif // TASKQUEUE_STATS #endif // TASKQUEUE_STATS
@ -383,7 +384,15 @@ void ParScanThreadStateSet::print_termination_stats_hdr(outputStream* const st)
st->print_raw_cr("--- --------- --------- ------ --------- ------ --------"); st->print_raw_cr("--- --------- --------- ------ --------- ------ --------");
} }
void ParScanThreadStateSet::print_termination_stats(outputStream* const st) { void ParScanThreadStateSet::print_termination_stats() {
LogHandle(gc, task, stats) log;
if (!log.is_debug()) {
return;
}
ResourceMark rm;
outputStream* st = log.debug_stream();
print_termination_stats_hdr(st); print_termination_stats_hdr(st);
for (int i = 0; i < length(); ++i) { for (int i = 0; i < length(); ++i) {
@ -404,7 +413,13 @@ void ParScanThreadStateSet::print_taskqueue_stats_hdr(outputStream* const st) {
st->print_raw("--- "); TaskQueueStats::print_header(2, st); st->cr(); st->print_raw("--- "); TaskQueueStats::print_header(2, st); st->cr();
} }
void ParScanThreadStateSet::print_taskqueue_stats(outputStream* const st) { void ParScanThreadStateSet::print_taskqueue_stats() {
if (!develop_log_is_enabled(Trace, gc, task, stats)) {
return;
}
LogHandle(gc, task, stats) log;
ResourceMark rm;
outputStream* st = log.trace_stream();
print_taskqueue_stats_hdr(st); print_taskqueue_stats_hdr(st);
TaskQueueStats totals; TaskQueueStats totals;
@ -823,9 +838,7 @@ void ParNewGeneration::handle_promotion_failed(GenCollectedHeap* gch, ParScanThr
_promo_failure_scan_stack.clear(true); // Clear cached segments. _promo_failure_scan_stack.clear(true); // Clear cached segments.
remove_forwarding_pointers(); remove_forwarding_pointers();
if (PrintGCDetails) { log_info(gc, promotion)("Promotion failed");
gclog_or_tty->print(" (promotion failed)");
}
// All the spaces are in play for mark-sweep. // All the spaces are in play for mark-sweep.
swap_spaces(); // Make life simpler for CMS || rescan; see 6483690. swap_spaces(); // Make life simpler for CMS || rescan; see 6483690.
from()->set_next_compaction_space(to()); from()->set_next_compaction_space(to());
@ -882,9 +895,7 @@ void ParNewGeneration::collect(bool full,
size_policy->minor_collection_begin(); size_policy->minor_collection_begin();
} }
GCTraceTime t1(GCCauseString("GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, NULL); GCTraceTime(Trace, gc) t1("ParNew", NULL, gch->gc_cause());
// Capture heap used before collection (for printing).
size_t gch_prev_used = gch->used();
age_table()->clear(); age_table()->clear();
to()->clear(SpaceDecorator::Mangle); to()->clear(SpaceDecorator::Mangle);
@ -990,12 +1001,8 @@ void ParNewGeneration::collect(bool full,
plab_stats()->adjust_desired_plab_sz(); plab_stats()->adjust_desired_plab_sz();
} }
if (PrintGC && !PrintGCDetails) { TASKQUEUE_STATS_ONLY(thread_state_set.print_termination_stats());
gch->print_heap_change(gch_prev_used); TASKQUEUE_STATS_ONLY(thread_state_set.print_taskqueue_stats());
}
TASKQUEUE_STATS_ONLY(if (PrintTerminationStats) thread_state_set.print_termination_stats());
TASKQUEUE_STATS_ONLY(if (PrintTaskqueue) thread_state_set.print_taskqueue_stats());
if (UseAdaptiveSizePolicy) { if (UseAdaptiveSizePolicy) {
size_policy->minor_collection_end(gch->gc_cause()); size_policy->minor_collection_end(gch->gc_cause());
@ -1150,11 +1157,9 @@ oop ParNewGeneration::copy_to_survivor_space(ParScanThreadState* par_scan_state,
// This code must come after the CAS test, or it will print incorrect // This code must come after the CAS test, or it will print incorrect
// information. // information.
if (TraceScavenge) { log_develop_trace(gc, scavenge)("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",
gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}", is_in_reserved(new_obj) ? "copying" : "tenuring",
is_in_reserved(new_obj) ? "copying" : "tenuring", new_obj->klass()->internal_name(), p2i(old), p2i(new_obj), new_obj->size());
new_obj->klass()->internal_name(), p2i(old), p2i(new_obj), new_obj->size());
}
if (forward_ptr == NULL) { if (forward_ptr == NULL) {
oop obj_to_push = new_obj; oop obj_to_push = new_obj;
@ -1176,9 +1181,7 @@ oop ParNewGeneration::copy_to_survivor_space(ParScanThreadState* par_scan_state,
) )
if (simulate_overflow || !par_scan_state->work_queue()->push(obj_to_push)) { if (simulate_overflow || !par_scan_state->work_queue()->push(obj_to_push)) {
// Add stats for overflow pushes. // Add stats for overflow pushes.
if (Verbose && PrintGCDetails) { log_develop_trace(gc)("Queue Overflow");
gclog_or_tty->print("queue overflow!\n");
}
push_on_overflow_list(old, par_scan_state); push_on_overflow_list(old, par_scan_state);
TASKQUEUE_STATS_ONLY(par_scan_state->taskqueue_stats().record_overflow(0)); TASKQUEUE_STATS_ONLY(par_scan_state->taskqueue_stats().record_overflow(0));
} }

View file

@ -30,6 +30,7 @@
#include "gc/shared/cardTableRS.hpp" #include "gc/shared/cardTableRS.hpp"
#include "gc/shared/genCollectedHeap.hpp" #include "gc/shared/genCollectedHeap.hpp"
#include "gc/shared/genOopClosures.inline.hpp" #include "gc/shared/genOopClosures.inline.hpp"
#include "logging/log.hpp"
template <class T> inline void ParScanWeakRefClosure::do_oop_work(T* p) { template <class T> inline void ParScanWeakRefClosure::do_oop_work(T* p) {
assert (!oopDesc::is_null(*p), "null weak reference?"); assert (!oopDesc::is_null(*p), "null weak reference?");
@ -108,11 +109,9 @@ inline void ParScanClosure::do_oop_work(T* p,
if (m->is_marked()) { // Contains forwarding pointer. if (m->is_marked()) { // Contains forwarding pointer.
new_obj = ParNewGeneration::real_forwardee(obj); new_obj = ParNewGeneration::real_forwardee(obj);
oopDesc::encode_store_heap_oop_not_null(p, new_obj); oopDesc::encode_store_heap_oop_not_null(p, new_obj);
if (TraceScavenge) { log_develop_trace(gc, scavenge)("{%s %s ( " PTR_FORMAT " ) " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",
gclog_or_tty->print_cr("{%s %s ( " PTR_FORMAT " ) " PTR_FORMAT " -> " PTR_FORMAT " (%d)}", "forwarded ",
"forwarded ", new_obj->klass()->internal_name(), p2i(p), p2i((void *)obj), p2i((void *)new_obj), new_obj->size());
new_obj->klass()->internal_name(), p2i(p), p2i((void *)obj), p2i((void *)new_obj), new_obj->size());
}
} else { } else {
size_t obj_sz = obj->size_given_klass(objK); size_t obj_sz = obj->size_given_klass(objK);
new_obj = _g->copy_to_survivor_space(_par_scan_state, obj, obj_sz, m); new_obj = _g->copy_to_survivor_space(_par_scan_state, obj, obj_sz, m);

View file

@ -132,7 +132,7 @@ class SpoolBlock: public FreeChunk {
} }
void print_on(outputStream* st) const; void print_on(outputStream* st) const;
void print() const { print_on(gclog_or_tty); } void print() const { print_on(tty); }
}; };
class PromotionInfo VALUE_OBJ_CLASS_SPEC { class PromotionInfo VALUE_OBJ_CLASS_SPEC {

View file

@ -28,7 +28,7 @@
#include "gc/cms/vmCMSOperations.hpp" #include "gc/cms/vmCMSOperations.hpp"
#include "gc/shared/gcLocker.inline.hpp" #include "gc/shared/gcLocker.inline.hpp"
#include "gc/shared/gcTimer.hpp" #include "gc/shared/gcTimer.hpp"
#include "gc/shared/gcTraceTime.hpp" #include "gc/shared/gcTraceTime.inline.hpp"
#include "gc/shared/isGCActiveMark.hpp" #include "gc/shared/isGCActiveMark.hpp"
#include "runtime/interfaceSupport.hpp" #include "runtime/interfaceSupport.hpp"
#include "runtime/os.hpp" #include "runtime/os.hpp"
@ -58,7 +58,7 @@ void VM_CMS_Operation::release_and_notify_pending_list_lock() {
void VM_CMS_Operation::verify_before_gc() { void VM_CMS_Operation::verify_before_gc() {
if (VerifyBeforeGC && if (VerifyBeforeGC &&
GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) { GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
GCTraceTime tm("Verify Before", false, false, _collector->_gc_timer_cm); GCTraceTime(Info, gc, verify) tm("Verify Before", _collector->_gc_timer_cm);
HandleMark hm; HandleMark hm;
FreelistLocker x(_collector); FreelistLocker x(_collector);
MutexLockerEx y(_collector->bitMapLock(), Mutex::_no_safepoint_check_flag); MutexLockerEx y(_collector->bitMapLock(), Mutex::_no_safepoint_check_flag);
@ -70,7 +70,7 @@ void VM_CMS_Operation::verify_before_gc() {
void VM_CMS_Operation::verify_after_gc() { void VM_CMS_Operation::verify_after_gc() {
if (VerifyAfterGC && if (VerifyAfterGC &&
GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) { GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
GCTraceTime tm("Verify After", false, false, _collector->_gc_timer_cm); GCTraceTime(Info, gc, verify) tm("Verify After", _collector->_gc_timer_cm);
HandleMark hm; HandleMark hm;
FreelistLocker x(_collector); FreelistLocker x(_collector);
MutexLockerEx y(_collector->bitMapLock(), Mutex::_no_safepoint_check_flag); MutexLockerEx y(_collector->bitMapLock(), Mutex::_no_safepoint_check_flag);

View file

@ -26,7 +26,6 @@
#include "gc/g1/collectionSetChooser.hpp" #include "gc/g1/collectionSetChooser.hpp"
#include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp"
#include "gc/g1/g1CollectorPolicy.hpp" #include "gc/g1/g1CollectorPolicy.hpp"
#include "gc/g1/g1ErgoVerbose.hpp"
#include "gc/shared/space.inline.hpp" #include "gc/shared/space.inline.hpp"
#include "runtime/atomic.inline.hpp" #include "runtime/atomic.inline.hpp"
@ -136,8 +135,8 @@ void CollectionSetChooser::sort_regions() {
assert(regions_at(i) != NULL, "Should be true by sorting!"); assert(regions_at(i) != NULL, "Should be true by sorting!");
} }
#endif // ASSERT #endif // ASSERT
if (G1PrintRegionLivenessInfo) { if (log_is_enabled(Trace, gc, liveness)) {
G1PrintRegionLivenessInfoClosure cl(gclog_or_tty, "Post-Sorting"); G1PrintRegionLivenessInfoClosure cl("Post-Sorting");
for (uint i = 0; i < _end; ++i) { for (uint i = 0; i < _end; ++i) {
HeapRegion* r = regions_at(i); HeapRegion* r = regions_at(i);
cl.doHeapRegion(r); cl.doHeapRegion(r);

View file

@ -28,6 +28,7 @@
#include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp"
#include "gc/g1/g1CollectorPolicy.hpp" #include "gc/g1/g1CollectorPolicy.hpp"
#include "gc/g1/suspendibleThreadSet.hpp" #include "gc/g1/suspendibleThreadSet.hpp"
#include "logging/log.hpp"
#include "memory/resourceArea.hpp" #include "memory/resourceArea.hpp"
#include "runtime/handles.inline.hpp" #include "runtime/handles.inline.hpp"
#include "runtime/mutexLocker.hpp" #include "runtime/mutexLocker.hpp"
@ -88,11 +89,8 @@ bool ConcurrentG1RefineThread::is_active() {
void ConcurrentG1RefineThread::activate() { void ConcurrentG1RefineThread::activate() {
MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag); MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
if (!is_primary()) { if (!is_primary()) {
if (G1TraceConcRefinement) { log_debug(gc, refine)("G1-Refine-activated worker %d, on threshold %d, current %d",
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); _worker_id, _threshold, JavaThread::dirty_card_queue_set().completed_buffers_num());
gclog_or_tty->print_cr("G1-Refine-activated worker %d, on threshold %d, current %d",
_worker_id, _threshold, (int)dcqs.completed_buffers_num());
}
set_active(true); set_active(true);
} else { } else {
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
@ -104,11 +102,8 @@ void ConcurrentG1RefineThread::activate() {
void ConcurrentG1RefineThread::deactivate() { void ConcurrentG1RefineThread::deactivate() {
MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag); MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
if (!is_primary()) { if (!is_primary()) {
if (G1TraceConcRefinement) { log_debug(gc, refine)("G1-Refine-deactivated worker %d, off threshold %d, current %d",
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); _worker_id, _deactivation_threshold, JavaThread::dirty_card_queue_set().completed_buffers_num());
gclog_or_tty->print_cr("G1-Refine-deactivated worker %d, off threshold %d, current %d",
_worker_id, _deactivation_threshold, (int)dcqs.completed_buffers_num());
}
set_active(false); set_active(false);
} else { } else {
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
@ -174,9 +169,7 @@ void ConcurrentG1RefineThread::run_service() {
} }
} }
if (G1TraceConcRefinement) { log_debug(gc, refine)("G1-Refine-stop");
gclog_or_tty->print_cr("G1-Refine-stop");
}
} }
void ConcurrentG1RefineThread::stop() { void ConcurrentG1RefineThread::stop() {

View file

@ -31,8 +31,6 @@
#include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp"
#include "gc/g1/g1CollectorPolicy.hpp" #include "gc/g1/g1CollectorPolicy.hpp"
#include "gc/g1/g1CollectorState.hpp" #include "gc/g1/g1CollectorState.hpp"
#include "gc/g1/g1ErgoVerbose.hpp"
#include "gc/g1/g1Log.hpp"
#include "gc/g1/g1OopClosures.inline.hpp" #include "gc/g1/g1OopClosures.inline.hpp"
#include "gc/g1/g1RemSet.hpp" #include "gc/g1/g1RemSet.hpp"
#include "gc/g1/g1StringDedup.hpp" #include "gc/g1/g1StringDedup.hpp"
@ -44,12 +42,13 @@
#include "gc/shared/gcId.hpp" #include "gc/shared/gcId.hpp"
#include "gc/shared/gcTimer.hpp" #include "gc/shared/gcTimer.hpp"
#include "gc/shared/gcTrace.hpp" #include "gc/shared/gcTrace.hpp"
#include "gc/shared/gcTraceTime.hpp" #include "gc/shared/gcTraceTime.inline.hpp"
#include "gc/shared/genOopClosures.inline.hpp" #include "gc/shared/genOopClosures.inline.hpp"
#include "gc/shared/referencePolicy.hpp" #include "gc/shared/referencePolicy.hpp"
#include "gc/shared/strongRootsScope.hpp" #include "gc/shared/strongRootsScope.hpp"
#include "gc/shared/taskqueue.inline.hpp" #include "gc/shared/taskqueue.inline.hpp"
#include "gc/shared/vmGCOperations.hpp" #include "gc/shared/vmGCOperations.hpp"
#include "logging/log.hpp"
#include "memory/allocation.hpp" #include "memory/allocation.hpp"
#include "memory/resourceArea.hpp" #include "memory/resourceArea.hpp"
#include "oops/oop.inline.hpp" #include "oops/oop.inline.hpp"
@ -232,9 +231,7 @@ void CMMarkStack::expand() {
// Clear expansion flag // Clear expansion flag
_should_expand = false; _should_expand = false;
if (_capacity == (jint) MarkStackSizeMax) { if (_capacity == (jint) MarkStackSizeMax) {
if (PrintGCDetails && Verbose) { log_trace(gc)("(benign) Can't expand marking stack capacity, at max size limit");
gclog_or_tty->print_cr(" (benign) Can't expand marking stack capacity, at max size limit");
}
return; return;
} }
// Double capacity if possible // Double capacity if possible
@ -254,12 +251,9 @@ void CMMarkStack::expand() {
_index = 0; _index = 0;
_capacity = new_capacity; _capacity = new_capacity;
} else { } else {
if (PrintGCDetails && Verbose) { // Failed to double capacity, continue;
// Failed to double capacity, continue; log_trace(gc)("(benign) Failed to expand marking stack capacity from " SIZE_FORMAT "K to " SIZE_FORMAT "K",
gclog_or_tty->print(" (benign) Failed to expand marking stack capacity from " _capacity / K, new_capacity / K);
SIZE_FORMAT "K to " SIZE_FORMAT "K",
_capacity / K, new_capacity / K);
}
} }
} }
@ -848,10 +842,7 @@ void ConcurrentMark::enter_first_sync_barrier(uint worker_id) {
// marking. // marking.
reset_marking_state(true /* clear_overflow */); reset_marking_state(true /* clear_overflow */);
if (G1Log::fine()) { log_info(gc)("Concurrent Mark reset for overflow");
gclog_or_tty->gclog_stamp();
gclog_or_tty->print_cr("[GC concurrent-mark-reset-for-overflow]");
}
} }
} }
@ -987,8 +978,6 @@ public:
}; };
void ConcurrentMark::scanRootRegions() { void ConcurrentMark::scanRootRegions() {
double scan_start = os::elapsedTime();
// Start of concurrent marking. // Start of concurrent marking.
ClassLoaderDataGraph::clear_claimed_marks(); ClassLoaderDataGraph::clear_claimed_marks();
@ -996,10 +985,7 @@ void ConcurrentMark::scanRootRegions() {
// at least one root region to scan. So, if it's false, we // at least one root region to scan. So, if it's false, we
// should not attempt to do any further work. // should not attempt to do any further work.
if (root_regions()->scan_in_progress()) { if (root_regions()->scan_in_progress()) {
if (G1Log::fine()) { GCTraceConcTime(Info, gc) tt("Concurrent Root Region Scan");
gclog_or_tty->gclog_stamp();
gclog_or_tty->print_cr("[GC concurrent-root-region-scan-start]");
}
_parallel_marking_threads = calc_parallel_marking_threads(); _parallel_marking_threads = calc_parallel_marking_threads();
assert(parallel_marking_threads() <= max_parallel_marking_threads(), assert(parallel_marking_threads() <= max_parallel_marking_threads(),
@ -1010,11 +996,6 @@ void ConcurrentMark::scanRootRegions() {
_parallel_workers->set_active_workers(active_workers); _parallel_workers->set_active_workers(active_workers);
_parallel_workers->run_task(&task); _parallel_workers->run_task(&task);
if (G1Log::fine()) {
gclog_or_tty->gclog_stamp();
gclog_or_tty->print_cr("[GC concurrent-root-region-scan-end, %1.7lf secs]", os::elapsedTime() - scan_start);
}
// It's possible that has_aborted() is true here without actually // It's possible that has_aborted() is true here without actually
// aborting the survivor scan earlier. This is OK as it's // aborting the survivor scan earlier. This is OK as it's
// mainly used for sanity checking. // mainly used for sanity checking.
@ -1049,22 +1030,6 @@ void ConcurrentMark::markFromRoots() {
print_stats(); print_stats();
} }
// Helper class to get rid of some boilerplate code.
class G1CMTraceTime : public StackObj {
GCTraceTimeImpl _gc_trace_time;
static bool doit_and_prepend(bool doit) {
if (doit) {
gclog_or_tty->put(' ');
}
return doit;
}
public:
G1CMTraceTime(const char* title, bool doit)
: _gc_trace_time(title, doit_and_prepend(doit), false, G1CollectedHeap::heap()->gc_timer_cm()) {
}
};
void ConcurrentMark::checkpointRootsFinal(bool clear_all_soft_refs) { void ConcurrentMark::checkpointRootsFinal(bool clear_all_soft_refs) {
// world is stopped at this checkpoint // world is stopped at this checkpoint
assert(SafepointSynchronize::is_at_safepoint(), assert(SafepointSynchronize::is_at_safepoint(),
@ -1083,8 +1048,7 @@ void ConcurrentMark::checkpointRootsFinal(bool clear_all_soft_refs) {
if (VerifyDuringGC) { if (VerifyDuringGC) {
HandleMark hm; // handle scope HandleMark hm; // handle scope
g1h->prepare_for_verify(); g1h->prepare_for_verify();
Universe::verify(VerifyOption_G1UsePrevMarking, Universe::verify(VerifyOption_G1UsePrevMarking, "During GC (before)");
" VerifyDuringGC:(before)");
} }
g1h->check_bitmaps("Remark Start"); g1h->check_bitmaps("Remark Start");
@ -1102,16 +1066,13 @@ void ConcurrentMark::checkpointRootsFinal(bool clear_all_soft_refs) {
if (has_overflown()) { if (has_overflown()) {
// Oops. We overflowed. Restart concurrent marking. // Oops. We overflowed. Restart concurrent marking.
_restart_for_overflow = true; _restart_for_overflow = true;
if (G1TraceMarkStackOverflow) { log_develop_trace(gc)("Remark led to restart for overflow.");
gclog_or_tty->print_cr("\nRemark led to restart for overflow.");
}
// Verify the heap w.r.t. the previous marking bitmap. // Verify the heap w.r.t. the previous marking bitmap.
if (VerifyDuringGC) { if (VerifyDuringGC) {
HandleMark hm; // handle scope HandleMark hm; // handle scope
g1h->prepare_for_verify(); g1h->prepare_for_verify();
Universe::verify(VerifyOption_G1UsePrevMarking, Universe::verify(VerifyOption_G1UsePrevMarking, "During GC (overflow)");
" VerifyDuringGC:(overflow)");
} }
// Clear the marking state because we will be restarting // Clear the marking state because we will be restarting
@ -1119,7 +1080,7 @@ void ConcurrentMark::checkpointRootsFinal(bool clear_all_soft_refs) {
reset_marking_state(); reset_marking_state();
} else { } else {
{ {
G1CMTraceTime trace("GC aggregate-data", G1Log::finer()); GCTraceTime(Debug, gc) trace("GC Aggregate Data", g1h->gc_timer_cm());
// Aggregate the per-task counting data that we have accumulated // Aggregate the per-task counting data that we have accumulated
// while marking. // while marking.
@ -1136,8 +1097,7 @@ void ConcurrentMark::checkpointRootsFinal(bool clear_all_soft_refs) {
if (VerifyDuringGC) { if (VerifyDuringGC) {
HandleMark hm; // handle scope HandleMark hm; // handle scope
g1h->prepare_for_verify(); g1h->prepare_for_verify();
Universe::verify(VerifyOption_G1UseNextMarking, Universe::verify(VerifyOption_G1UseNextMarking, "During GC (after)");
" VerifyDuringGC:(after)");
} }
g1h->check_bitmaps("Remark End"); g1h->check_bitmaps("Remark End");
assert(!restart_for_overflow(), "sanity"); assert(!restart_for_overflow(), "sanity");
@ -1656,8 +1616,7 @@ void ConcurrentMark::cleanup() {
if (VerifyDuringGC) { if (VerifyDuringGC) {
HandleMark hm; // handle scope HandleMark hm; // handle scope
g1h->prepare_for_verify(); g1h->prepare_for_verify();
Universe::verify(VerifyOption_G1UsePrevMarking, Universe::verify(VerifyOption_G1UsePrevMarking, "During GC (before)");
" VerifyDuringGC:(before)");
} }
g1h->check_bitmaps("Cleanup Start"); g1h->check_bitmaps("Cleanup Start");
@ -1699,8 +1658,8 @@ void ConcurrentMark::cleanup() {
double this_final_counting_time = (count_end - start); double this_final_counting_time = (count_end - start);
_total_counting_time += this_final_counting_time; _total_counting_time += this_final_counting_time;
if (G1PrintRegionLivenessInfo) { if (log_is_enabled(Trace, gc, liveness)) {
G1PrintRegionLivenessInfoClosure cl(gclog_or_tty, "Post-Marking"); G1PrintRegionLivenessInfoClosure cl("Post-Marking");
_g1h->heap_region_iterate(&cl); _g1h->heap_region_iterate(&cl);
} }
@ -1743,10 +1702,6 @@ void ConcurrentMark::cleanup() {
double end = os::elapsedTime(); double end = os::elapsedTime();
_cleanup_times.add((end - start) * 1000.0); _cleanup_times.add((end - start) * 1000.0);
if (G1Log::fine()) {
g1h->g1_policy()->print_heap_transition(start_used_bytes);
}
// Clean up will have freed any regions completely full of garbage. // Clean up will have freed any regions completely full of garbage.
// Update the soft reference policy with the new heap occupancy. // Update the soft reference policy with the new heap occupancy.
Universe::update_heap_info_at_gc(); Universe::update_heap_info_at_gc();
@ -1754,8 +1709,7 @@ void ConcurrentMark::cleanup() {
if (VerifyDuringGC) { if (VerifyDuringGC) {
HandleMark hm; // handle scope HandleMark hm; // handle scope
g1h->prepare_for_verify(); g1h->prepare_for_verify();
Universe::verify(VerifyOption_G1UsePrevMarking, Universe::verify(VerifyOption_G1UsePrevMarking, "During GC (after)");
" VerifyDuringGC:(after)");
} }
g1h->check_bitmaps("Cleanup End"); g1h->check_bitmaps("Cleanup End");
@ -1788,11 +1742,9 @@ void ConcurrentMark::completeCleanup() {
_cleanup_list.verify_optional(); _cleanup_list.verify_optional();
FreeRegionList tmp_free_list("Tmp Free List"); FreeRegionList tmp_free_list("Tmp Free List");
if (G1ConcRegionFreeingVerbose) { log_develop_trace(gc, freelist)("G1ConcRegionFreeing [complete cleanup] : "
gclog_or_tty->print_cr("G1ConcRegionFreeing [complete cleanup] : " "cleanup list has %u entries",
"cleanup list has %u entries", _cleanup_list.length());
_cleanup_list.length());
}
// No one else should be accessing the _cleanup_list at this point, // No one else should be accessing the _cleanup_list at this point,
// so it is not necessary to take any locks // so it is not necessary to take any locks
@ -1810,13 +1762,11 @@ void ConcurrentMark::completeCleanup() {
// region from the _cleanup_list). // region from the _cleanup_list).
if ((tmp_free_list.length() % G1SecondaryFreeListAppendLength == 0) || if ((tmp_free_list.length() % G1SecondaryFreeListAppendLength == 0) ||
_cleanup_list.is_empty()) { _cleanup_list.is_empty()) {
if (G1ConcRegionFreeingVerbose) { log_develop_trace(gc, freelist)("G1ConcRegionFreeing [complete cleanup] : "
gclog_or_tty->print_cr("G1ConcRegionFreeing [complete cleanup] : " "appending %u entries to the secondary_free_list, "
"appending %u entries to the secondary_free_list, " "cleanup list still has %u entries",
"cleanup list still has %u entries", tmp_free_list.length(),
tmp_free_list.length(), _cleanup_list.length());
_cleanup_list.length());
}
{ {
MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag); MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag);
@ -2073,7 +2023,7 @@ void ConcurrentMark::weakRefsWork(bool clear_all_soft_refs) {
// Inner scope to exclude the cleaning of the string and symbol // Inner scope to exclude the cleaning of the string and symbol
// tables from the displayed time. // tables from the displayed time.
{ {
G1CMTraceTime t("GC ref-proc", G1Log::finer()); GCTraceTime(Debug, gc) trace("GC Ref Proc", g1h->gc_timer_cm());
ReferenceProcessor* rp = g1h->ref_processor_cm(); ReferenceProcessor* rp = g1h->ref_processor_cm();
@ -2163,24 +2113,24 @@ void ConcurrentMark::weakRefsWork(bool clear_all_soft_refs) {
// Unload Klasses, String, Symbols, Code Cache, etc. // Unload Klasses, String, Symbols, Code Cache, etc.
{ {
G1CMTraceTime trace("Unloading", G1Log::finer()); GCTraceTime(Debug, gc) trace("Unloading", g1h->gc_timer_cm());
if (ClassUnloadingWithConcurrentMark) { if (ClassUnloadingWithConcurrentMark) {
bool purged_classes; bool purged_classes;
{ {
G1CMTraceTime trace("System Dictionary Unloading", G1Log::finest()); GCTraceTime(Trace, gc) trace("System Dictionary Unloading", g1h->gc_timer_cm());
purged_classes = SystemDictionary::do_unloading(&g1_is_alive, false /* Defer klass cleaning */); purged_classes = SystemDictionary::do_unloading(&g1_is_alive, false /* Defer klass cleaning */);
} }
{ {
G1CMTraceTime trace("Parallel Unloading", G1Log::finest()); GCTraceTime(Trace, gc) trace("Parallel Unloading", g1h->gc_timer_cm());
weakRefsWorkParallelPart(&g1_is_alive, purged_classes); weakRefsWorkParallelPart(&g1_is_alive, purged_classes);
} }
} }
if (G1StringDedup::is_enabled()) { if (G1StringDedup::is_enabled()) {
G1CMTraceTime trace("String Deduplication Unlink", G1Log::finest()); GCTraceTime(Trace, gc) trace("String Deduplication Unlink", g1h->gc_timer_cm());
G1StringDedup::unlink(&g1_is_alive); G1StringDedup::unlink(&g1_is_alive);
} }
} }
@ -2301,7 +2251,7 @@ void ConcurrentMark::checkpointRootsFinalWork() {
HandleMark hm; HandleMark hm;
G1CollectedHeap* g1h = G1CollectedHeap::heap(); G1CollectedHeap* g1h = G1CollectedHeap::heap();
G1CMTraceTime trace("Finalize Marking", G1Log::finer()); GCTraceTime(Debug, gc) trace("Finalize Marking", g1h->gc_timer_cm());
g1h->ensure_parsability(false); g1h->ensure_parsability(false);
@ -2614,12 +2564,13 @@ void ConcurrentMark::clear_all_count_data() {
} }
void ConcurrentMark::print_stats() { void ConcurrentMark::print_stats() {
if (G1MarkingVerboseLevel > 0) { if (!log_is_enabled(Debug, gc, stats)) {
gclog_or_tty->print_cr("---------------------------------------------------------------------"); return;
for (size_t i = 0; i < _active_tasks; ++i) { }
_tasks[i]->print_stats(); log_debug(gc, stats)("---------------------------------------------------------------------");
gclog_or_tty->print_cr("---------------------------------------------------------------------"); for (size_t i = 0; i < _active_tasks; ++i) {
} _tasks[i]->print_stats();
log_debug(gc, stats)("---------------------------------------------------------------------");
} }
} }
@ -2663,16 +2614,21 @@ void ConcurrentMark::abort() {
static void print_ms_time_info(const char* prefix, const char* name, static void print_ms_time_info(const char* prefix, const char* name,
NumberSeq& ns) { NumberSeq& ns) {
gclog_or_tty->print_cr("%s%5d %12s: total time = %8.2f s (avg = %8.2f ms).", log_trace(gc, marking)("%s%5d %12s: total time = %8.2f s (avg = %8.2f ms).",
prefix, ns.num(), name, ns.sum()/1000.0, ns.avg()); prefix, ns.num(), name, ns.sum()/1000.0, ns.avg());
if (ns.num() > 0) { if (ns.num() > 0) {
gclog_or_tty->print_cr("%s [std. dev = %8.2f ms, max = %8.2f ms]", log_trace(gc, marking)("%s [std. dev = %8.2f ms, max = %8.2f ms]",
prefix, ns.sd(), ns.maximum()); prefix, ns.sd(), ns.maximum());
} }
} }
void ConcurrentMark::print_summary_info() { void ConcurrentMark::print_summary_info() {
gclog_or_tty->print_cr(" Concurrent marking:"); LogHandle(gc, marking) log;
if (!log.is_trace()) {
return;
}
log.trace(" Concurrent marking:");
print_ms_time_info(" ", "init marks", _init_times); print_ms_time_info(" ", "init marks", _init_times);
print_ms_time_info(" ", "remarks", _remark_times); print_ms_time_info(" ", "remarks", _remark_times);
{ {
@ -2681,25 +2637,16 @@ void ConcurrentMark::print_summary_info() {
} }
print_ms_time_info(" ", "cleanups", _cleanup_times); print_ms_time_info(" ", "cleanups", _cleanup_times);
gclog_or_tty->print_cr(" Final counting total time = %8.2f s (avg = %8.2f ms).", log.trace(" Final counting total time = %8.2f s (avg = %8.2f ms).",
_total_counting_time, _total_counting_time, (_cleanup_times.num() > 0 ? _total_counting_time * 1000.0 / (double)_cleanup_times.num() : 0.0));
(_cleanup_times.num() > 0 ? _total_counting_time * 1000.0 /
(double)_cleanup_times.num()
: 0.0));
if (G1ScrubRemSets) { if (G1ScrubRemSets) {
gclog_or_tty->print_cr(" RS scrub total time = %8.2f s (avg = %8.2f ms).", log.trace(" RS scrub total time = %8.2f s (avg = %8.2f ms).",
_total_rs_scrub_time, _total_rs_scrub_time, (_cleanup_times.num() > 0 ? _total_rs_scrub_time * 1000.0 / (double)_cleanup_times.num() : 0.0));
(_cleanup_times.num() > 0 ? _total_rs_scrub_time * 1000.0 /
(double)_cleanup_times.num()
: 0.0));
} }
gclog_or_tty->print_cr(" Total stop_world time = %8.2f s.", log.trace(" Total stop_world time = %8.2f s.",
(_init_times.sum() + _remark_times.sum() + (_init_times.sum() + _remark_times.sum() + _cleanup_times.sum())/1000.0);
_cleanup_times.sum())/1000.0); log.trace(" Total concurrent time = %8.2f s (%8.2f s marking).",
gclog_or_tty->print_cr(" Total concurrent time = %8.2f s " cmThread()->vtime_accum(), cmThread()->vtime_mark_accum());
"(%8.2f s marking).",
cmThread()->vtime_accum(),
cmThread()->vtime_mark_accum());
} }
void ConcurrentMark::print_worker_threads_on(outputStream* st) const { void ConcurrentMark::print_worker_threads_on(outputStream* st) const {
@ -3079,15 +3026,15 @@ void CMTask::drain_satb_buffers() {
} }
void CMTask::print_stats() { void CMTask::print_stats() {
gclog_or_tty->print_cr("Marking Stats, task = %u, calls = %d", log_debug(gc, stats)("Marking Stats, task = %u, calls = %d",
_worker_id, _calls); _worker_id, _calls);
gclog_or_tty->print_cr(" Elapsed time = %1.2lfms, Termination time = %1.2lfms", log_debug(gc, stats)(" Elapsed time = %1.2lfms, Termination time = %1.2lfms",
_elapsed_time_ms, _termination_time_ms); _elapsed_time_ms, _termination_time_ms);
gclog_or_tty->print_cr(" Step Times (cum): num = %d, avg = %1.2lfms, sd = %1.2lfms", log_debug(gc, stats)(" Step Times (cum): num = %d, avg = %1.2lfms, sd = %1.2lfms",
_step_times_ms.num(), _step_times_ms.avg(), _step_times_ms.num(), _step_times_ms.avg(),
_step_times_ms.sd()); _step_times_ms.sd());
gclog_or_tty->print_cr(" max = %1.2lfms, total = %1.2lfms", log_debug(gc, stats)(" max = %1.2lfms, total = %1.2lfms",
_step_times_ms.maximum(), _step_times_ms.sum()); _step_times_ms.maximum(), _step_times_ms.sum());
} }
bool ConcurrentMark::try_stealing(uint worker_id, int* hash_seed, oop& obj) { bool ConcurrentMark::try_stealing(uint worker_id, int* hash_seed, oop& obj) {
@ -3587,9 +3534,8 @@ CMTask::CMTask(uint worker_id,
#define G1PPRL_SUM_MB_PERC_FORMAT(tag) G1PPRL_SUM_MB_FORMAT(tag) " / %1.2f %%" #define G1PPRL_SUM_MB_PERC_FORMAT(tag) G1PPRL_SUM_MB_FORMAT(tag) " / %1.2f %%"
G1PrintRegionLivenessInfoClosure:: G1PrintRegionLivenessInfoClosure::
G1PrintRegionLivenessInfoClosure(outputStream* out, const char* phase_name) G1PrintRegionLivenessInfoClosure(const char* phase_name)
: _out(out), : _total_used_bytes(0), _total_capacity_bytes(0),
_total_used_bytes(0), _total_capacity_bytes(0),
_total_prev_live_bytes(0), _total_next_live_bytes(0), _total_prev_live_bytes(0), _total_next_live_bytes(0),
_hum_used_bytes(0), _hum_capacity_bytes(0), _hum_used_bytes(0), _hum_capacity_bytes(0),
_hum_prev_live_bytes(0), _hum_next_live_bytes(0), _hum_prev_live_bytes(0), _hum_next_live_bytes(0),
@ -3599,38 +3545,37 @@ G1PrintRegionLivenessInfoClosure(outputStream* out, const char* phase_name)
double now = os::elapsedTime(); double now = os::elapsedTime();
// Print the header of the output. // Print the header of the output.
_out->cr(); log_trace(gc, liveness)(G1PPRL_LINE_PREFIX" PHASE %s @ %1.3f", phase_name, now);
_out->print_cr(G1PPRL_LINE_PREFIX" PHASE %s @ %1.3f", phase_name, now); log_trace(gc, liveness)(G1PPRL_LINE_PREFIX" HEAP"
_out->print_cr(G1PPRL_LINE_PREFIX" HEAP" G1PPRL_SUM_ADDR_FORMAT("reserved")
G1PPRL_SUM_ADDR_FORMAT("reserved") G1PPRL_SUM_BYTE_FORMAT("region-size"),
G1PPRL_SUM_BYTE_FORMAT("region-size"), p2i(g1_reserved.start()), p2i(g1_reserved.end()),
p2i(g1_reserved.start()), p2i(g1_reserved.end()), HeapRegion::GrainBytes);
HeapRegion::GrainBytes); log_trace(gc, liveness)(G1PPRL_LINE_PREFIX);
_out->print_cr(G1PPRL_LINE_PREFIX); log_trace(gc, liveness)(G1PPRL_LINE_PREFIX
_out->print_cr(G1PPRL_LINE_PREFIX G1PPRL_TYPE_H_FORMAT
G1PPRL_TYPE_H_FORMAT G1PPRL_ADDR_BASE_H_FORMAT
G1PPRL_ADDR_BASE_H_FORMAT G1PPRL_BYTE_H_FORMAT
G1PPRL_BYTE_H_FORMAT G1PPRL_BYTE_H_FORMAT
G1PPRL_BYTE_H_FORMAT G1PPRL_BYTE_H_FORMAT
G1PPRL_BYTE_H_FORMAT G1PPRL_DOUBLE_H_FORMAT
G1PPRL_DOUBLE_H_FORMAT G1PPRL_BYTE_H_FORMAT
G1PPRL_BYTE_H_FORMAT G1PPRL_BYTE_H_FORMAT,
G1PPRL_BYTE_H_FORMAT, "type", "address-range",
"type", "address-range", "used", "prev-live", "next-live", "gc-eff",
"used", "prev-live", "next-live", "gc-eff", "remset", "code-roots");
"remset", "code-roots"); log_trace(gc, liveness)(G1PPRL_LINE_PREFIX
_out->print_cr(G1PPRL_LINE_PREFIX G1PPRL_TYPE_H_FORMAT
G1PPRL_TYPE_H_FORMAT G1PPRL_ADDR_BASE_H_FORMAT
G1PPRL_ADDR_BASE_H_FORMAT G1PPRL_BYTE_H_FORMAT
G1PPRL_BYTE_H_FORMAT G1PPRL_BYTE_H_FORMAT
G1PPRL_BYTE_H_FORMAT G1PPRL_BYTE_H_FORMAT
G1PPRL_BYTE_H_FORMAT G1PPRL_DOUBLE_H_FORMAT
G1PPRL_DOUBLE_H_FORMAT G1PPRL_BYTE_H_FORMAT
G1PPRL_BYTE_H_FORMAT G1PPRL_BYTE_H_FORMAT,
G1PPRL_BYTE_H_FORMAT, "", "",
"", "", "(bytes)", "(bytes)", "(bytes)", "(bytes/ms)",
"(bytes)", "(bytes)", "(bytes)", "(bytes/ms)", "(bytes)", "(bytes)");
"(bytes)", "(bytes)");
} }
// It takes as a parameter a reference to one of the _hum_* fields, it // It takes as a parameter a reference to one of the _hum_* fields, it
@ -3701,18 +3646,18 @@ bool G1PrintRegionLivenessInfoClosure::doHeapRegion(HeapRegion* r) {
_total_strong_code_roots_bytes += strong_code_roots_bytes; _total_strong_code_roots_bytes += strong_code_roots_bytes;
// Print a line for this particular region. // Print a line for this particular region.
_out->print_cr(G1PPRL_LINE_PREFIX log_trace(gc, liveness)(G1PPRL_LINE_PREFIX
G1PPRL_TYPE_FORMAT G1PPRL_TYPE_FORMAT
G1PPRL_ADDR_BASE_FORMAT G1PPRL_ADDR_BASE_FORMAT
G1PPRL_BYTE_FORMAT G1PPRL_BYTE_FORMAT
G1PPRL_BYTE_FORMAT G1PPRL_BYTE_FORMAT
G1PPRL_BYTE_FORMAT G1PPRL_BYTE_FORMAT
G1PPRL_DOUBLE_FORMAT G1PPRL_DOUBLE_FORMAT
G1PPRL_BYTE_FORMAT G1PPRL_BYTE_FORMAT
G1PPRL_BYTE_FORMAT, G1PPRL_BYTE_FORMAT,
type, p2i(bottom), p2i(end), type, p2i(bottom), p2i(end),
used_bytes, prev_live_bytes, next_live_bytes, gc_eff, used_bytes, prev_live_bytes, next_live_bytes, gc_eff,
remset_bytes, strong_code_roots_bytes); remset_bytes, strong_code_roots_bytes);
return false; return false;
} }
@ -3721,23 +3666,22 @@ G1PrintRegionLivenessInfoClosure::~G1PrintRegionLivenessInfoClosure() {
// add static memory usages to remembered set sizes // add static memory usages to remembered set sizes
_total_remset_bytes += HeapRegionRemSet::fl_mem_size() + HeapRegionRemSet::static_mem_size(); _total_remset_bytes += HeapRegionRemSet::fl_mem_size() + HeapRegionRemSet::static_mem_size();
// Print the footer of the output. // Print the footer of the output.
_out->print_cr(G1PPRL_LINE_PREFIX); log_trace(gc, liveness)(G1PPRL_LINE_PREFIX);
_out->print_cr(G1PPRL_LINE_PREFIX log_trace(gc, liveness)(G1PPRL_LINE_PREFIX
" SUMMARY" " SUMMARY"
G1PPRL_SUM_MB_FORMAT("capacity") G1PPRL_SUM_MB_FORMAT("capacity")
G1PPRL_SUM_MB_PERC_FORMAT("used") G1PPRL_SUM_MB_PERC_FORMAT("used")
G1PPRL_SUM_MB_PERC_FORMAT("prev-live") G1PPRL_SUM_MB_PERC_FORMAT("prev-live")
G1PPRL_SUM_MB_PERC_FORMAT("next-live") G1PPRL_SUM_MB_PERC_FORMAT("next-live")
G1PPRL_SUM_MB_FORMAT("remset") G1PPRL_SUM_MB_FORMAT("remset")
G1PPRL_SUM_MB_FORMAT("code-roots"), G1PPRL_SUM_MB_FORMAT("code-roots"),
bytes_to_mb(_total_capacity_bytes), bytes_to_mb(_total_capacity_bytes),
bytes_to_mb(_total_used_bytes), bytes_to_mb(_total_used_bytes),
perc(_total_used_bytes, _total_capacity_bytes), perc(_total_used_bytes, _total_capacity_bytes),
bytes_to_mb(_total_prev_live_bytes), bytes_to_mb(_total_prev_live_bytes),
perc(_total_prev_live_bytes, _total_capacity_bytes), perc(_total_prev_live_bytes, _total_capacity_bytes),
bytes_to_mb(_total_next_live_bytes), bytes_to_mb(_total_next_live_bytes),
perc(_total_next_live_bytes, _total_capacity_bytes), perc(_total_next_live_bytes, _total_capacity_bytes),
bytes_to_mb(_total_remset_bytes), bytes_to_mb(_total_remset_bytes),
bytes_to_mb(_total_strong_code_roots_bytes)); bytes_to_mb(_total_strong_code_roots_bytes));
_out->cr();
} }

View file

@ -978,8 +978,6 @@ public:
// after we sort the old regions at the end of the cleanup operation. // after we sort the old regions at the end of the cleanup operation.
class G1PrintRegionLivenessInfoClosure: public HeapRegionClosure { class G1PrintRegionLivenessInfoClosure: public HeapRegionClosure {
private: private:
outputStream* _out;
// Accumulators for these values. // Accumulators for these values.
size_t _total_used_bytes; size_t _total_used_bytes;
size_t _total_capacity_bytes; size_t _total_capacity_bytes;
@ -1024,7 +1022,7 @@ private:
public: public:
// The header and footer are printed in the constructor and // The header and footer are printed in the constructor and
// destructor respectively. // destructor respectively.
G1PrintRegionLivenessInfoClosure(outputStream* out, const char* phase_name); G1PrintRegionLivenessInfoClosure(const char* phase_name);
virtual bool doHeapRegion(HeapRegion* r); virtual bool doHeapRegion(HeapRegion* r);
~G1PrintRegionLivenessInfoClosure(); ~G1PrintRegionLivenessInfoClosure();
}; };

View file

@ -26,12 +26,13 @@
#include "gc/g1/concurrentMarkThread.inline.hpp" #include "gc/g1/concurrentMarkThread.inline.hpp"
#include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp"
#include "gc/g1/g1CollectorPolicy.hpp" #include "gc/g1/g1CollectorPolicy.hpp"
#include "gc/g1/g1Log.hpp"
#include "gc/g1/g1MMUTracker.hpp" #include "gc/g1/g1MMUTracker.hpp"
#include "gc/g1/suspendibleThreadSet.hpp" #include "gc/g1/suspendibleThreadSet.hpp"
#include "gc/g1/vm_operations_g1.hpp" #include "gc/g1/vm_operations_g1.hpp"
#include "gc/shared/gcId.hpp" #include "gc/shared/gcId.hpp"
#include "gc/shared/gcTrace.hpp" #include "gc/shared/gcTrace.hpp"
#include "gc/shared/gcTraceTime.inline.hpp"
#include "logging/log.hpp"
#include "memory/resourceArea.hpp" #include "memory/resourceArea.hpp"
#include "runtime/vmThread.hpp" #include "runtime/vmThread.hpp"
@ -78,20 +79,6 @@ public:
} }
}; };
// We want to avoid that the logging from the concurrent thread is mixed
// with the logging from a STW GC. So, if necessary join the STS to ensure
// that the logging is done either before or after the STW logging.
void ConcurrentMarkThread::cm_log(bool doit, bool join_sts, const char* fmt, ...) {
if (doit) {
SuspendibleThreadSetJoiner sts_joiner(join_sts);
va_list args;
va_start(args, fmt);
gclog_or_tty->gclog_stamp();
gclog_or_tty->vprint_cr(fmt, args);
va_end(args);
}
}
// Marking pauses can be scheduled flexibly, so we might delay marking to meet MMU. // Marking pauses can be scheduled flexibly, so we might delay marking to meet MMU.
void ConcurrentMarkThread::delay_to_keep_mmu(G1CollectorPolicy* g1_policy, bool remark) { void ConcurrentMarkThread::delay_to_keep_mmu(G1CollectorPolicy* g1_policy, bool remark) {
if (g1_policy->adaptive_young_list_length()) { if (g1_policy->adaptive_young_list_length()) {
@ -143,8 +130,11 @@ void ConcurrentMarkThread::run_service() {
_cm->scanRootRegions(); _cm->scanRootRegions();
} }
double mark_start_sec = os::elapsedTime(); // It would be nice to use the GCTraceConcTime class here but
cm_log(G1Log::fine(), true, "[GC concurrent-mark-start]"); // the "end" logging is inside the loop and not at the end of
// a scope. Mimicking the same log output as GCTraceConcTime instead.
jlong mark_start = os::elapsed_counter();
log_info(gc)("Concurrent Mark (%.3fs)", TimeHelper::counter_to_seconds(mark_start));
int iter = 0; int iter = 0;
do { do {
@ -154,20 +144,22 @@ void ConcurrentMarkThread::run_service() {
} }
double mark_end_time = os::elapsedVTime(); double mark_end_time = os::elapsedVTime();
double mark_end_sec = os::elapsedTime(); jlong mark_end = os::elapsed_counter();
_vtime_mark_accum += (mark_end_time - cycle_start); _vtime_mark_accum += (mark_end_time - cycle_start);
if (!cm()->has_aborted()) { if (!cm()->has_aborted()) {
delay_to_keep_mmu(g1_policy, true /* remark */); delay_to_keep_mmu(g1_policy, true /* remark */);
log_info(gc)("Concurrent Mark (%.3fs, %.3fs) %.3fms",
cm_log(G1Log::fine(), true, "[GC concurrent-mark-end, %1.7lf secs]", mark_end_sec - mark_start_sec); TimeHelper::counter_to_seconds(mark_start),
TimeHelper::counter_to_seconds(mark_end),
TimeHelper::counter_to_millis(mark_end - mark_start));
CMCheckpointRootsFinalClosure final_cl(_cm); CMCheckpointRootsFinalClosure final_cl(_cm);
VM_CGC_Operation op(&final_cl, "GC remark", true /* needs_pll */); VM_CGC_Operation op(&final_cl, "Pause Remark", true /* needs_pll */);
VMThread::execute(&op); VMThread::execute(&op);
} }
if (cm()->restart_for_overflow()) { if (cm()->restart_for_overflow()) {
cm_log(G1TraceMarkStackOverflow, true, "Restarting conc marking because of MS overflow in remark (restart #%d).", iter); log_debug(gc)("Restarting conc marking because of MS overflow in remark (restart #%d).", iter);
cm_log(G1Log::fine(), true, "[GC concurrent-mark-restart-for-overflow]"); log_info(gc)("Concurrent Mark restart for overflow");
} }
} while (cm()->restart_for_overflow()); } while (cm()->restart_for_overflow());
@ -181,7 +173,7 @@ void ConcurrentMarkThread::run_service() {
delay_to_keep_mmu(g1_policy, false /* cleanup */); delay_to_keep_mmu(g1_policy, false /* cleanup */);
CMCleanUp cl_cl(_cm); CMCleanUp cl_cl(_cm);
VM_CGC_Operation op(&cl_cl, "GC cleanup", false /* needs_pll */); VM_CGC_Operation op(&cl_cl, "Pause Cleanup", false /* needs_pll */);
VMThread::execute(&op); VMThread::execute(&op);
} else { } else {
// We don't want to update the marking status if a GC pause // We don't want to update the marking status if a GC pause
@ -201,8 +193,7 @@ void ConcurrentMarkThread::run_service() {
// place, it would wait for us to process the regions // place, it would wait for us to process the regions
// reclaimed by cleanup. // reclaimed by cleanup.
double cleanup_start_sec = os::elapsedTime(); GCTraceConcTime(Info, gc) tt("Concurrent Cleanup");
cm_log(G1Log::fine(), false, "[GC concurrent-cleanup-start]");
// Now do the concurrent cleanup operation. // Now do the concurrent cleanup operation.
_cm->completeCleanup(); _cm->completeCleanup();
@ -217,9 +208,6 @@ void ConcurrentMarkThread::run_service() {
// while it's trying to join the STS, which is conditional on // while it's trying to join the STS, which is conditional on
// the GC workers finishing. // the GC workers finishing.
g1h->reset_free_regions_coming(); g1h->reset_free_regions_coming();
double cleanup_end_sec = os::elapsedTime();
cm_log(G1Log::fine(), true, "[GC concurrent-cleanup-end, %1.7lf secs]", cleanup_end_sec - cleanup_start_sec);
} }
guarantee(cm()->cleanup_list_is_empty(), guarantee(cm()->cleanup_list_is_empty(),
"at this point there should be no regions on the cleanup list"); "at this point there should be no regions on the cleanup list");
@ -253,7 +241,7 @@ void ConcurrentMarkThread::run_service() {
if (!cm()->has_aborted()) { if (!cm()->has_aborted()) {
g1_policy->record_concurrent_mark_cleanup_completed(); g1_policy->record_concurrent_mark_cleanup_completed();
} else { } else {
cm_log(G1Log::fine(), false, "[GC concurrent-mark-abort]"); log_info(gc)("Concurrent Mark abort");
} }
} }

View file

@ -40,7 +40,6 @@ class ConcurrentMarkThread: public ConcurrentGCThread {
double _vtime_accum; // Accumulated virtual time. double _vtime_accum; // Accumulated virtual time.
double _vtime_mark_accum; double _vtime_mark_accum;
void cm_log(bool doit, bool join_sts, const char* fmt, ...) ATTRIBUTE_PRINTF(4, 5);
public: public:
virtual void run(); virtual void run();

View file

@ -27,6 +27,7 @@
#include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp"
#include "gc/g1/heapRegion.hpp" #include "gc/g1/heapRegion.hpp"
#include "gc/shared/space.hpp" #include "gc/shared/space.hpp"
#include "logging/log.hpp"
#include "oops/oop.inline.hpp" #include "oops/oop.inline.hpp"
#include "runtime/java.hpp" #include "runtime/java.hpp"
#include "services/memTracker.hpp" #include "services/memTracker.hpp"
@ -50,14 +51,9 @@ G1BlockOffsetSharedArray::G1BlockOffsetSharedArray(MemRegion heap, G1RegionToSpa
storage->set_mapping_changed_listener(&_listener); storage->set_mapping_changed_listener(&_listener);
if (TraceBlockOffsetTable) { log_trace(gc, bot)("G1BlockOffsetSharedArray::G1BlockOffsetSharedArray: ");
gclog_or_tty->print_cr("G1BlockOffsetSharedArray::G1BlockOffsetSharedArray: "); log_trace(gc, bot)(" rs.base(): " PTR_FORMAT " rs.size(): " SIZE_FORMAT " rs end(): " PTR_FORMAT,
gclog_or_tty->print_cr(" " p2i(bot_reserved.start()), bot_reserved.byte_size(), p2i(bot_reserved.end()));
" rs.base(): " PTR_FORMAT
" rs.size(): " SIZE_FORMAT
" rs end(): " PTR_FORMAT,
p2i(bot_reserved.start()), bot_reserved.byte_size(), p2i(bot_reserved.end()));
}
} }
bool G1BlockOffsetSharedArray::is_card_boundary(HeapWord* p) const { bool G1BlockOffsetSharedArray::is_card_boundary(HeapWord* p) const {

File diff suppressed because it is too large Load diff

View file

@ -290,8 +290,7 @@ private:
void verify_before_gc(); void verify_before_gc();
void verify_after_gc(); void verify_after_gc();
void log_gc_header(); void log_gc_footer(double pause_time_counter);
void log_gc_footer(double pause_time_sec);
void trace_heap(GCWhen::Type when, const GCTracer* tracer); void trace_heap(GCWhen::Type when, const GCTracer* tracer);
@ -704,8 +703,8 @@ protected:
void shrink_helper(size_t expand_bytes); void shrink_helper(size_t expand_bytes);
#if TASKQUEUE_STATS #if TASKQUEUE_STATS
static void print_taskqueue_stats_hdr(outputStream* const st = gclog_or_tty); static void print_taskqueue_stats_hdr(outputStream* const st);
void print_taskqueue_stats(outputStream* const st = gclog_or_tty) const; void print_taskqueue_stats() const;
void reset_taskqueue_stats(); void reset_taskqueue_stats();
#endif // TASKQUEUE_STATS #endif // TASKQUEUE_STATS
@ -738,10 +737,9 @@ protected:
void post_evacuate_collection_set(EvacuationInfo& evacuation_info, G1ParScanThreadStateSet* pss); void post_evacuate_collection_set(EvacuationInfo& evacuation_info, G1ParScanThreadStateSet* pss);
// Print the header for the per-thread termination statistics. // Print the header for the per-thread termination statistics.
static void print_termination_stats_hdr(outputStream* const st); static void print_termination_stats_hdr();
// Print actual per-thread termination statistics. // Print actual per-thread termination statistics.
void print_termination_stats(outputStream* const st, void print_termination_stats(uint worker_id,
uint worker_id,
double elapsed_ms, double elapsed_ms,
double strong_roots_ms, double strong_roots_ms,
double term_ms, double term_ms,
@ -968,6 +966,10 @@ public:
return CollectedHeap::G1CollectedHeap; return CollectedHeap::G1CollectedHeap;
} }
virtual const char* name() const {
return "G1";
}
const G1CollectorState* collector_state() const { return &_collector_state; } const G1CollectorState* collector_state() const { return &_collector_state; }
G1CollectorState* collector_state() { return &_collector_state; } G1CollectorState* collector_state() { return &_collector_state; }
@ -1365,6 +1367,10 @@ public:
YoungList* young_list() const { return _young_list; } YoungList* young_list() const { return _young_list; }
uint old_regions_count() const { return _old_set.length(); }
uint humongous_regions_count() const { return _humongous_set.length(); }
// debugging // debugging
bool check_young_list_well_formed() { bool check_young_list_well_formed() {
return _young_list->check_list_well_formed(); return _young_list->check_list_well_formed();
@ -1482,10 +1488,7 @@ public:
// Currently there is only one place where this is called with // Currently there is only one place where this is called with
// vo == UseMarkWord, which is to verify the marking during a // vo == UseMarkWord, which is to verify the marking during a
// full GC. // full GC.
void verify(bool silent, VerifyOption vo); void verify(VerifyOption vo);
// Override; it uses the "prev" marking information
virtual void verify(bool silent);
// The methods below are here for convenience and dispatch the // The methods below are here for convenience and dispatch the
// appropriate method depending on value of the given VerifyOption // appropriate method depending on value of the given VerifyOption

View file

@ -29,9 +29,7 @@
#include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp"
#include "gc/g1/g1CollectorPolicy.hpp" #include "gc/g1/g1CollectorPolicy.hpp"
#include "gc/g1/g1IHOPControl.hpp" #include "gc/g1/g1IHOPControl.hpp"
#include "gc/g1/g1ErgoVerbose.hpp"
#include "gc/g1/g1GCPhaseTimes.hpp" #include "gc/g1/g1GCPhaseTimes.hpp"
#include "gc/g1/g1Log.hpp"
#include "gc/g1/heapRegion.inline.hpp" #include "gc/g1/heapRegion.inline.hpp"
#include "gc/g1/heapRegionRemSet.hpp" #include "gc/g1/heapRegionRemSet.hpp"
#include "gc/shared/gcPolicyCounters.hpp" #include "gc/shared/gcPolicyCounters.hpp"
@ -121,6 +119,8 @@ G1CollectorPolicy::G1CollectorPolicy() :
_eden_used_bytes_before_gc(0), _eden_used_bytes_before_gc(0),
_survivor_used_bytes_before_gc(0), _survivor_used_bytes_before_gc(0),
_old_used_bytes_before_gc(0),
_humongous_used_bytes_before_gc(0),
_heap_used_bytes_before_gc(0), _heap_used_bytes_before_gc(0),
_metaspace_used_bytes_before_gc(0), _metaspace_used_bytes_before_gc(0),
_eden_capacity_bytes_before_gc(0), _eden_capacity_bytes_before_gc(0),
@ -177,18 +177,6 @@ G1CollectorPolicy::G1CollectorPolicy() :
HeapRegion::setup_heap_region_size(InitialHeapSize, MaxHeapSize); HeapRegion::setup_heap_region_size(InitialHeapSize, MaxHeapSize);
HeapRegionRemSet::setup_remset_size(); HeapRegionRemSet::setup_remset_size();
G1ErgoVerbose::initialize();
if (PrintAdaptiveSizePolicy) {
// Currently, we only use a single switch for all the heuristics.
G1ErgoVerbose::set_enabled(true);
// Given that we don't currently have a verboseness level
// parameter, we'll hardcode this to high. This can be easily
// changed in the future.
G1ErgoVerbose::set_level(ErgoHigh);
} else {
G1ErgoVerbose::set_enabled(false);
}
_recent_prev_end_times_for_all_gcs_sec->add(os::elapsedTime()); _recent_prev_end_times_for_all_gcs_sec->add(os::elapsedTime());
_prev_collection_pause_end_ms = os::elapsedTime() * 1000.0; _prev_collection_pause_end_ms = os::elapsedTime() * 1000.0;
clear_ratio_check_data(); clear_ratio_check_data();
@ -791,7 +779,7 @@ G1CollectorPolicy::verify_young_ages(HeapRegion* head,
curr = curr->get_next_young_region()) { curr = curr->get_next_young_region()) {
SurvRateGroup* group = curr->surv_rate_group(); SurvRateGroup* group = curr->surv_rate_group();
if (group == NULL && !curr->is_survivor()) { if (group == NULL && !curr->is_survivor()) {
gclog_or_tty->print_cr("## %s: encountered NULL surv_rate_group", name); log_info(gc, verify)("## %s: encountered NULL surv_rate_group", name);
ret = false; ret = false;
} }
@ -799,13 +787,12 @@ G1CollectorPolicy::verify_young_ages(HeapRegion* head,
int age = curr->age_in_surv_rate_group(); int age = curr->age_in_surv_rate_group();
if (age < 0) { if (age < 0) {
gclog_or_tty->print_cr("## %s: encountered negative age", name); log_info(gc, verify)("## %s: encountered negative age", name);
ret = false; ret = false;
} }
if (age <= prev_age) { if (age <= prev_age) {
gclog_or_tty->print_cr("## %s: region ages are not strictly increasing " log_info(gc, verify)("## %s: region ages are not strictly increasing (%d, %d)", name, age, prev_age);
"(%d, %d)", name, age, prev_age);
ret = false; ret = false;
} }
prev_age = age; prev_age = age;
@ -982,38 +969,15 @@ bool G1CollectorPolicy::need_to_start_conc_mark(const char* source, size_t alloc
size_t alloc_byte_size = alloc_word_size * HeapWordSize; size_t alloc_byte_size = alloc_word_size * HeapWordSize;
size_t marking_request_bytes = cur_used_bytes + alloc_byte_size; size_t marking_request_bytes = cur_used_bytes + alloc_byte_size;
bool result = false;
if (marking_request_bytes > marking_initiating_used_threshold) { if (marking_request_bytes > marking_initiating_used_threshold) {
if (collector_state()->gcs_are_young() && !collector_state()->last_young_gc()) { result = collector_state()->gcs_are_young() && !collector_state()->last_young_gc();
ergo_verbose5(ErgoConcCycles, log_debug(gc, ergo, ihop)("%s occupancy: " SIZE_FORMAT "B allocation request: " SIZE_FORMAT "B threshold: " SIZE_FORMAT "B (%1.2f) source: %s",
"request concurrent cycle initiation", result ? "Request concurrent cycle initiation (occupancy higher than threshold)" : "Do not request concurrent cycle initiation (still doing mixed collections)",
ergo_format_reason("occupancy higher than threshold") cur_used_bytes, alloc_byte_size, marking_initiating_used_threshold, (double) marking_initiating_used_threshold / _g1->capacity() * 100, source);
ergo_format_byte("occupancy")
ergo_format_byte("allocation request")
ergo_format_byte_perc("threshold")
ergo_format_str("source"),
cur_used_bytes,
alloc_byte_size,
marking_initiating_used_threshold,
(double) marking_initiating_used_threshold / _g1->capacity() * 100,
source);
return true;
} else {
ergo_verbose5(ErgoConcCycles,
"do not request concurrent cycle initiation",
ergo_format_reason("still doing mixed collections")
ergo_format_byte("occupancy")
ergo_format_byte("allocation request")
ergo_format_byte_perc("threshold")
ergo_format_str("source"),
cur_used_bytes,
alloc_byte_size,
marking_initiating_used_threshold,
(double) InitiatingHeapOccupancyPercent,
source);
}
} }
return false; return result;
} }
// Anything below that is considered to be zero // Anything below that is considered to be zero
@ -1027,13 +991,7 @@ void G1CollectorPolicy::record_collection_pause_end(double pause_time_ms, size_t
bool last_pause_included_initial_mark = false; bool last_pause_included_initial_mark = false;
bool update_stats = !_g1->evacuation_failed(); bool update_stats = !_g1->evacuation_failed();
#ifndef PRODUCT NOT_PRODUCT(_short_lived_surv_rate_group->print());
if (G1YoungSurvRateVerbose) {
gclog_or_tty->cr();
_short_lived_surv_rate_group->print();
// do that for any other surv rate groups too
}
#endif // PRODUCT
record_pause(young_gc_pause_kind(), end_time_sec - pause_time_ms / 1000.0, end_time_sec); record_pause(young_gc_pause_kind(), end_time_sec - pause_time_ms / 1000.0, end_time_sec);
@ -1228,13 +1186,9 @@ void G1CollectorPolicy::record_collection_pause_end(double pause_time_ms, size_t
double scan_hcc_time_ms = average_time_ms(G1GCPhaseTimes::ScanHCC); double scan_hcc_time_ms = average_time_ms(G1GCPhaseTimes::ScanHCC);
if (update_rs_time_goal_ms < scan_hcc_time_ms) { if (update_rs_time_goal_ms < scan_hcc_time_ms) {
ergo_verbose2(ErgoTiming, log_debug(gc, ergo, refine)("Adjust concurrent refinement thresholds (scanning the HCC expected to take longer than Update RS time goal)."
"adjust concurrent refinement thresholds", "Update RS time goal: %1.2fms Scan HCC time: %1.2fms",
ergo_format_reason("Scanning the HCC expected to take longer than Update RS time goal") update_rs_time_goal_ms, scan_hcc_time_ms);
ergo_format_ms("Update RS time goal")
ergo_format_ms("Scan HCC time"),
update_rs_time_goal_ms,
scan_hcc_time_ms);
update_rs_time_goal_ms = 0; update_rs_time_goal_ms = 0;
} else { } else {
@ -1312,65 +1266,37 @@ void G1CollectorPolicy::record_heap_size_info_at_start(bool full) {
_eden_used_bytes_before_gc = young_list->eden_used_bytes(); _eden_used_bytes_before_gc = young_list->eden_used_bytes();
_survivor_used_bytes_before_gc = young_list->survivor_used_bytes(); _survivor_used_bytes_before_gc = young_list->survivor_used_bytes();
_heap_capacity_bytes_before_gc = _g1->capacity(); _heap_capacity_bytes_before_gc = _g1->capacity();
_old_used_bytes_before_gc = _g1->old_regions_count() * HeapRegion::GrainBytes;
_humongous_used_bytes_before_gc = _g1->humongous_regions_count() * HeapRegion::GrainBytes;
_heap_used_bytes_before_gc = _g1->used(); _heap_used_bytes_before_gc = _g1->used();
_eden_capacity_bytes_before_gc = (_young_list_target_length * HeapRegion::GrainBytes) - _survivor_used_bytes_before_gc;
_eden_capacity_bytes_before_gc = _metaspace_used_bytes_before_gc = MetaspaceAux::used_bytes();
(_young_list_target_length * HeapRegion::GrainBytes) - _survivor_used_bytes_before_gc;
if (full) {
_metaspace_used_bytes_before_gc = MetaspaceAux::used_bytes();
}
} }
void G1CollectorPolicy::print_heap_transition(size_t bytes_before) const { void G1CollectorPolicy::print_detailed_heap_transition() const {
size_t bytes_after = _g1->used();
size_t capacity = _g1->capacity();
gclog_or_tty->print(" " SIZE_FORMAT "%s->" SIZE_FORMAT "%s(" SIZE_FORMAT "%s)",
byte_size_in_proper_unit(bytes_before),
proper_unit_for_byte_size(bytes_before),
byte_size_in_proper_unit(bytes_after),
proper_unit_for_byte_size(bytes_after),
byte_size_in_proper_unit(capacity),
proper_unit_for_byte_size(capacity));
}
void G1CollectorPolicy::print_heap_transition() const {
print_heap_transition(_heap_used_bytes_before_gc);
}
void G1CollectorPolicy::print_detailed_heap_transition(bool full) const {
YoungList* young_list = _g1->young_list(); YoungList* young_list = _g1->young_list();
size_t eden_used_bytes_after_gc = young_list->eden_used_bytes(); size_t eden_used_bytes_after_gc = young_list->eden_used_bytes();
size_t survivor_used_bytes_after_gc = young_list->survivor_used_bytes(); size_t survivor_used_bytes_after_gc = young_list->survivor_used_bytes();
size_t heap_used_bytes_after_gc = _g1->used(); size_t heap_used_bytes_after_gc = _g1->used();
size_t old_used_bytes_after_gc = _g1->old_regions_count() * HeapRegion::GrainBytes;
size_t humongous_used_bytes_after_gc = _g1->humongous_regions_count() * HeapRegion::GrainBytes;
size_t heap_capacity_bytes_after_gc = _g1->capacity(); size_t heap_capacity_bytes_after_gc = _g1->capacity();
size_t eden_capacity_bytes_after_gc = size_t eden_capacity_bytes_after_gc =
(_young_list_target_length * HeapRegion::GrainBytes) - survivor_used_bytes_after_gc; (_young_list_target_length * HeapRegion::GrainBytes) - survivor_used_bytes_after_gc;
size_t survivor_capacity_bytes_after_gc = _max_survivor_regions * HeapRegion::GrainBytes;
gclog_or_tty->print( log_info(gc, heap)("Eden: " SIZE_FORMAT "K->" SIZE_FORMAT "K(" SIZE_FORMAT "K)",
" [Eden: " EXT_SIZE_FORMAT "(" EXT_SIZE_FORMAT ")->" EXT_SIZE_FORMAT "(" EXT_SIZE_FORMAT ") " _eden_used_bytes_before_gc / K, eden_used_bytes_after_gc /K, eden_capacity_bytes_after_gc /K);
"Survivors: " EXT_SIZE_FORMAT "->" EXT_SIZE_FORMAT " " log_info(gc, heap)("Survivor: " SIZE_FORMAT "K->" SIZE_FORMAT "K(" SIZE_FORMAT "K)",
"Heap: " EXT_SIZE_FORMAT "(" EXT_SIZE_FORMAT ")->" _survivor_used_bytes_before_gc / K, survivor_used_bytes_after_gc /K, survivor_capacity_bytes_after_gc /K);
EXT_SIZE_FORMAT "(" EXT_SIZE_FORMAT ")]", log_info(gc, heap)("Old: " SIZE_FORMAT "K->" SIZE_FORMAT "K",
EXT_SIZE_PARAMS(_eden_used_bytes_before_gc), _old_used_bytes_before_gc / K, old_used_bytes_after_gc /K);
EXT_SIZE_PARAMS(_eden_capacity_bytes_before_gc), log_info(gc, heap)("Humongous: " SIZE_FORMAT "K->" SIZE_FORMAT "K",
EXT_SIZE_PARAMS(eden_used_bytes_after_gc), _humongous_used_bytes_before_gc / K, humongous_used_bytes_after_gc /K);
EXT_SIZE_PARAMS(eden_capacity_bytes_after_gc),
EXT_SIZE_PARAMS(_survivor_used_bytes_before_gc),
EXT_SIZE_PARAMS(survivor_used_bytes_after_gc),
EXT_SIZE_PARAMS(_heap_used_bytes_before_gc),
EXT_SIZE_PARAMS(_heap_capacity_bytes_before_gc),
EXT_SIZE_PARAMS(heap_used_bytes_after_gc),
EXT_SIZE_PARAMS(heap_capacity_bytes_after_gc));
if (full) { MetaspaceAux::print_metaspace_change(_metaspace_used_bytes_before_gc);
MetaspaceAux::print_metaspace_change(_metaspace_used_bytes_before_gc);
}
gclog_or_tty->cr();
} }
void G1CollectorPolicy::print_phases(double pause_time_sec) { void G1CollectorPolicy::print_phases(double pause_time_sec) {
@ -1690,17 +1616,9 @@ size_t G1CollectorPolicy::expansion_amount() {
} }
} }
ergo_verbose5(ErgoHeapSizing, log_debug(gc, ergo, heap)("Attempt heap expansion (recent GC overhead higher than threshold after GC) "
"attempt heap expansion", "recent GC overhead: %1.2f %% threshold: %1.2f %% uncommitted: " SIZE_FORMAT "B base expansion amount and scale: " SIZE_FORMAT "B (%1.2f%%)",
ergo_format_reason("recent GC overhead higher than " recent_gc_overhead, threshold, uncommitted_bytes, expand_bytes, scale_factor * 100);
"threshold after GC")
ergo_format_perc("recent GC overhead")
ergo_format_perc("current threshold")
ergo_format_byte("uncommitted")
ergo_format_byte_perc("base expansion amount and scale"),
recent_gc_overhead, threshold,
uncommitted_bytes,
expand_bytes, scale_factor * 100);
expand_bytes = static_cast<size_t>(expand_bytes * scale_factor); expand_bytes = static_cast<size_t>(expand_bytes * scale_factor);
@ -1783,19 +1701,11 @@ bool G1CollectorPolicy::force_initial_mark_if_outside_cycle(GCCause::Cause gc_ca
// even while we are still in the process of reclaiming memory. // even while we are still in the process of reclaiming memory.
bool during_cycle = _g1->concurrent_mark()->cmThread()->during_cycle(); bool during_cycle = _g1->concurrent_mark()->cmThread()->during_cycle();
if (!during_cycle) { if (!during_cycle) {
ergo_verbose1(ErgoConcCycles, log_debug(gc, ergo)("Request concurrent cycle initiation (requested by GC cause). GC cause: %s", GCCause::to_string(gc_cause));
"request concurrent cycle initiation",
ergo_format_reason("requested by GC cause")
ergo_format_str("GC cause"),
GCCause::to_string(gc_cause));
collector_state()->set_initiate_conc_mark_if_possible(true); collector_state()->set_initiate_conc_mark_if_possible(true);
return true; return true;
} else { } else {
ergo_verbose1(ErgoConcCycles, log_debug(gc, ergo)("Do not request concurrent cycle initiation (concurrent cycle already in progress). GC cause: %s", GCCause::to_string(gc_cause));
"do not request concurrent cycle initiation",
ergo_format_reason("concurrent cycle already in progress")
ergo_format_str("GC cause"),
GCCause::to_string(gc_cause));
return false; return false;
} }
} }
@ -1823,9 +1733,7 @@ void G1CollectorPolicy::decide_on_conc_mark_initiation() {
if (!about_to_start_mixed_phase() && collector_state()->gcs_are_young()) { if (!about_to_start_mixed_phase() && collector_state()->gcs_are_young()) {
// Initiate a new initial mark if there is no marking or reclamation going on. // Initiate a new initial mark if there is no marking or reclamation going on.
initiate_conc_mark(); initiate_conc_mark();
ergo_verbose0(ErgoConcCycles, log_debug(gc, ergo)("Initiate concurrent cycle (concurrent cycle initiation requested)");
"initiate concurrent cycle",
ergo_format_reason("concurrent cycle initiation requested"));
} else if (_g1->is_user_requested_concurrent_full_gc(_g1->gc_cause())) { } else if (_g1->is_user_requested_concurrent_full_gc(_g1->gc_cause())) {
// Initiate a user requested initial mark. An initial mark must be young only // Initiate a user requested initial mark. An initial mark must be young only
// GC, so the collector state must be updated to reflect this. // GC, so the collector state must be updated to reflect this.
@ -1834,9 +1742,7 @@ void G1CollectorPolicy::decide_on_conc_mark_initiation() {
abort_time_to_mixed_tracking(); abort_time_to_mixed_tracking();
initiate_conc_mark(); initiate_conc_mark();
ergo_verbose0(ErgoConcCycles, log_debug(gc, ergo)("Initiate concurrent cycle (user requested concurrent cycle)");
"initiate concurrent cycle",
ergo_format_reason("user requested concurrent cycle"));
} else { } else {
// The concurrent marking thread is still finishing up the // The concurrent marking thread is still finishing up the
// previous cycle. If we start one right now the two cycles // previous cycle. If we start one right now the two cycles
@ -1850,9 +1756,7 @@ void G1CollectorPolicy::decide_on_conc_mark_initiation() {
// and, if it's in a yield point, it's waiting for us to // and, if it's in a yield point, it's waiting for us to
// finish. So, at this point we will not start a cycle and we'll // finish. So, at this point we will not start a cycle and we'll
// let the concurrent marking thread complete the last one. // let the concurrent marking thread complete the last one.
ergo_verbose0(ErgoConcCycles, log_debug(gc, ergo)("Do not initiate concurrent cycle (concurrent cycle already in progress)");
"do not initiate concurrent cycle",
ergo_format_reason("concurrent cycle already in progress"));
} }
} }
} }
@ -2197,9 +2101,7 @@ void G1CollectorPolicy::abort_time_to_mixed_tracking() {
bool G1CollectorPolicy::next_gc_should_be_mixed(const char* true_action_str, bool G1CollectorPolicy::next_gc_should_be_mixed(const char* true_action_str,
const char* false_action_str) const { const char* false_action_str) const {
if (cset_chooser()->is_empty()) { if (cset_chooser()->is_empty()) {
ergo_verbose0(ErgoMixedGCs, log_debug(gc, ergo)("%s (candidate old regions not available)", false_action_str);
false_action_str,
ergo_format_reason("candidate old regions not available"));
return false; return false;
} }
@ -2208,27 +2110,12 @@ bool G1CollectorPolicy::next_gc_should_be_mixed(const char* true_action_str,
double reclaimable_perc = reclaimable_bytes_perc(reclaimable_bytes); double reclaimable_perc = reclaimable_bytes_perc(reclaimable_bytes);
double threshold = (double) G1HeapWastePercent; double threshold = (double) G1HeapWastePercent;
if (reclaimable_perc <= threshold) { if (reclaimable_perc <= threshold) {
ergo_verbose4(ErgoMixedGCs, log_debug(gc, ergo)("%s (reclaimable percentage not over threshold). candidate old regions: %u reclaimable: " SIZE_FORMAT " (%1.2f) threshold: " UINTX_FORMAT,
false_action_str, false_action_str, cset_chooser()->remaining_regions(), reclaimable_bytes, reclaimable_perc, G1HeapWastePercent);
ergo_format_reason("reclaimable percentage not over threshold")
ergo_format_region("candidate old regions")
ergo_format_byte_perc("reclaimable")
ergo_format_perc("threshold"),
cset_chooser()->remaining_regions(),
reclaimable_bytes,
reclaimable_perc, threshold);
return false; return false;
} }
log_debug(gc, ergo)("%s (candidate old regions available). candidate old regions: %u reclaimable: " SIZE_FORMAT " (%1.2f) threshold: " UINTX_FORMAT,
ergo_verbose4(ErgoMixedGCs, true_action_str, cset_chooser()->remaining_regions(), reclaimable_bytes, reclaimable_perc, G1HeapWastePercent);
true_action_str,
ergo_format_reason("candidate old regions available")
ergo_format_region("candidate old regions")
ergo_format_byte_perc("reclaimable")
ergo_format_perc("threshold"),
cset_chooser()->remaining_regions(),
reclaimable_bytes,
reclaimable_perc, threshold);
return true; return true;
} }
@ -2284,13 +2171,8 @@ double G1CollectorPolicy::finalize_young_cset_part(double target_pause_time_ms)
double base_time_ms = predict_base_elapsed_time_ms(_pending_cards); double base_time_ms = predict_base_elapsed_time_ms(_pending_cards);
double time_remaining_ms = MAX2(target_pause_time_ms - base_time_ms, 0.0); double time_remaining_ms = MAX2(target_pause_time_ms - base_time_ms, 0.0);
ergo_verbose4(ErgoCSetConstruction | ErgoHigh, log_trace(gc, ergo, cset)("Start choosing CSet. pending cards: " SIZE_FORMAT " predicted base time: %1.2fms remaining time: %1.2fms target pause time: %1.2fms",
"start choosing CSet", _pending_cards, base_time_ms, time_remaining_ms, target_pause_time_ms);
ergo_format_size("_pending_cards")
ergo_format_ms("predicted base time")
ergo_format_ms("remaining time")
ergo_format_ms("target pause time"),
_pending_cards, base_time_ms, time_remaining_ms, target_pause_time_ms);
collector_state()->set_last_gc_was_young(collector_state()->gcs_are_young()); collector_state()->set_last_gc_was_young(collector_state()->gcs_are_young());
@ -2326,15 +2208,8 @@ double G1CollectorPolicy::finalize_young_cset_part(double target_pause_time_ms)
_collection_set_bytes_used_before = _inc_cset_bytes_used_before; _collection_set_bytes_used_before = _inc_cset_bytes_used_before;
time_remaining_ms = MAX2(time_remaining_ms - _inc_cset_predicted_elapsed_time_ms, 0.0); time_remaining_ms = MAX2(time_remaining_ms - _inc_cset_predicted_elapsed_time_ms, 0.0);
ergo_verbose4(ErgoCSetConstruction | ErgoHigh, log_trace(gc, ergo, cset)("Add young regions to CSet. eden: %u regions, survivors: %u regions, predicted young region time: %1.2fms, target pause time: %1.2fms",
"add young regions to CSet", eden_region_length, survivor_region_length, _inc_cset_predicted_elapsed_time_ms, target_pause_time_ms);
ergo_format_region("eden")
ergo_format_region("survivors")
ergo_format_ms("predicted young region time")
ergo_format_ms("target pause time"),
eden_region_length, survivor_region_length,
_inc_cset_predicted_elapsed_time_ms,
target_pause_time_ms);
// The number of recorded young regions is the incremental // The number of recorded young regions is the incremental
// collection set's current size // collection set's current size
@ -2363,12 +2238,8 @@ void G1CollectorPolicy::finalize_old_cset_part(double time_remaining_ms) {
while (hr != NULL) { while (hr != NULL) {
if (old_cset_region_length() >= max_old_cset_length) { if (old_cset_region_length() >= max_old_cset_length) {
// Added maximum number of old regions to the CSet. // Added maximum number of old regions to the CSet.
ergo_verbose2(ErgoCSetConstruction, log_debug(gc, ergo, cset)("Finish adding old regions to CSet (old CSet region num reached max). old %u regions, max %u regions",
"finish adding old regions to CSet", old_cset_region_length(), max_old_cset_length);
ergo_format_reason("old CSet region num reached max")
ergo_format_region("old")
ergo_format_region("max"),
old_cset_region_length(), max_old_cset_length);
break; break;
} }
@ -2382,17 +2253,9 @@ void G1CollectorPolicy::finalize_old_cset_part(double time_remaining_ms) {
// We've added enough old regions that the amount of uncollected // We've added enough old regions that the amount of uncollected
// reclaimable space is at or below the waste threshold. Stop // reclaimable space is at or below the waste threshold. Stop
// adding old regions to the CSet. // adding old regions to the CSet.
ergo_verbose5(ErgoCSetConstruction, log_debug(gc, ergo, cset)("Finish adding old regions to CSet (reclaimable percentage not over threshold). "
"finish adding old regions to CSet", "old %u regions, max %u regions, reclaimable: " SIZE_FORMAT "B (%1.2f%%) threshold: " UINTX_FORMAT "%%",
ergo_format_reason("reclaimable percentage not over threshold") old_cset_region_length(), max_old_cset_length, reclaimable_bytes, reclaimable_perc, G1HeapWastePercent);
ergo_format_region("old")
ergo_format_region("max")
ergo_format_byte_perc("reclaimable")
ergo_format_perc("threshold"),
old_cset_region_length(),
max_old_cset_length,
reclaimable_bytes,
reclaimable_perc, threshold);
break; break;
} }
@ -2404,15 +2267,9 @@ void G1CollectorPolicy::finalize_old_cset_part(double time_remaining_ms) {
if (old_cset_region_length() >= min_old_cset_length) { if (old_cset_region_length() >= min_old_cset_length) {
// We have added the minimum number of old regions to the CSet, // We have added the minimum number of old regions to the CSet,
// we are done with this CSet. // we are done with this CSet.
ergo_verbose4(ErgoCSetConstruction, log_debug(gc, ergo, cset)("Finish adding old regions to CSet (predicted time is too high). "
"finish adding old regions to CSet", "predicted time: %1.2fms, remaining time: %1.2fms old %u regions, min %u regions",
ergo_format_reason("predicted time is too high") predicted_time_ms, time_remaining_ms, old_cset_region_length(), min_old_cset_length);
ergo_format_ms("predicted time")
ergo_format_ms("remaining time")
ergo_format_region("old")
ergo_format_region("min"),
predicted_time_ms, time_remaining_ms,
old_cset_region_length(), min_old_cset_length);
break; break;
} }
@ -2424,12 +2281,9 @@ void G1CollectorPolicy::finalize_old_cset_part(double time_remaining_ms) {
if (old_cset_region_length() >= min_old_cset_length) { if (old_cset_region_length() >= min_old_cset_length) {
// In the non-auto-tuning case, we'll finish adding regions // In the non-auto-tuning case, we'll finish adding regions
// to the CSet if we reach the minimum. // to the CSet if we reach the minimum.
ergo_verbose2(ErgoCSetConstruction,
"finish adding old regions to CSet", log_debug(gc, ergo, cset)("Finish adding old regions to CSet (old CSet region num reached min). old %u regions, min %u regions",
ergo_format_reason("old CSet region num reached min") old_cset_region_length(), min_old_cset_length);
ergo_format_region("old")
ergo_format_region("min"),
old_cset_region_length(), min_old_cset_length);
break; break;
} }
} }
@ -2444,26 +2298,16 @@ void G1CollectorPolicy::finalize_old_cset_part(double time_remaining_ms) {
hr = cset_chooser()->peek(); hr = cset_chooser()->peek();
} }
if (hr == NULL) { if (hr == NULL) {
ergo_verbose0(ErgoCSetConstruction, log_debug(gc, ergo, cset)("Finish adding old regions to CSet (candidate old regions not available)");
"finish adding old regions to CSet",
ergo_format_reason("candidate old regions not available"));
} }
if (expensive_region_num > 0) { if (expensive_region_num > 0) {
// We print the information once here at the end, predicated on // We print the information once here at the end, predicated on
// whether we added any apparently expensive regions or not, to // whether we added any apparently expensive regions or not, to
// avoid generating output per region. // avoid generating output per region.
ergo_verbose4(ErgoCSetConstruction, log_debug(gc, ergo, cset)("Added expensive regions to CSet (old CSet region num not reached min)."
"added expensive regions to CSet", "old %u regions, expensive: %u regions, min %u regions, remaining time: %1.2fms",
ergo_format_reason("old CSet region num not reached min") old_cset_region_length(), expensive_region_num, min_old_cset_length, time_remaining_ms);
ergo_format_region("old")
ergo_format_region("expensive")
ergo_format_region("min")
ergo_format_ms("remaining time"),
old_cset_region_length(),
expensive_region_num,
min_old_cset_length,
time_remaining_ms);
} }
cset_chooser()->verify(); cset_chooser()->verify();
@ -2471,13 +2315,8 @@ void G1CollectorPolicy::finalize_old_cset_part(double time_remaining_ms) {
stop_incremental_cset_building(); stop_incremental_cset_building();
ergo_verbose3(ErgoCSetConstruction, log_debug(gc, ergo, cset)("Finish choosing CSet. old %u regions, predicted old region time: %1.2fms, time remaining: %1.2f",
"finish choosing CSet", old_cset_region_length(), predicted_old_time_ms, time_remaining_ms);
ergo_format_region("old")
ergo_format_ms("predicted old region time")
ergo_format_ms("time remaining"),
old_cset_region_length(),
predicted_old_time_ms, time_remaining_ms);
double non_young_end_time_sec = os::elapsedTime(); double non_young_end_time_sec = os::elapsedTime();
phase_times()->record_non_young_cset_choice_time_ms((non_young_end_time_sec - non_young_start_time_sec) * 1000.0); phase_times()->record_non_young_cset_choice_time_ms((non_young_end_time_sec - non_young_start_time_sec) * 1000.0);
@ -2536,14 +2375,14 @@ void TraceYoungGenTimeData::increment_mixed_collection_count() {
void TraceYoungGenTimeData::print_summary(const char* str, void TraceYoungGenTimeData::print_summary(const char* str,
const NumberSeq* seq) const { const NumberSeq* seq) const {
double sum = seq->sum(); double sum = seq->sum();
gclog_or_tty->print_cr("%-27s = %8.2lf s (avg = %8.2lf ms)", tty->print_cr("%-27s = %8.2lf s (avg = %8.2lf ms)",
str, sum / 1000.0, seq->avg()); str, sum / 1000.0, seq->avg());
} }
void TraceYoungGenTimeData::print_summary_sd(const char* str, void TraceYoungGenTimeData::print_summary_sd(const char* str,
const NumberSeq* seq) const { const NumberSeq* seq) const {
print_summary(str, seq); print_summary(str, seq);
gclog_or_tty->print_cr("%45s = %5d, std dev = %8.2lf ms, max = %8.2lf ms)", tty->print_cr("%45s = %5d, std dev = %8.2lf ms, max = %8.2lf ms)",
"(num", seq->num(), seq->sd(), seq->maximum()); "(num", seq->num(), seq->sd(), seq->maximum());
} }
@ -2552,18 +2391,18 @@ void TraceYoungGenTimeData::print() const {
return; return;
} }
gclog_or_tty->print_cr("ALL PAUSES"); tty->print_cr("ALL PAUSES");
print_summary_sd(" Total", &_total); print_summary_sd(" Total", &_total);
gclog_or_tty->cr(); tty->cr();
gclog_or_tty->cr(); tty->cr();
gclog_or_tty->print_cr(" Young GC Pauses: %8d", _young_pause_num); tty->print_cr(" Young GC Pauses: %8d", _young_pause_num);
gclog_or_tty->print_cr(" Mixed GC Pauses: %8d", _mixed_pause_num); tty->print_cr(" Mixed GC Pauses: %8d", _mixed_pause_num);
gclog_or_tty->cr(); tty->cr();
gclog_or_tty->print_cr("EVACUATION PAUSES"); tty->print_cr("EVACUATION PAUSES");
if (_young_pause_num == 0 && _mixed_pause_num == 0) { if (_young_pause_num == 0 && _mixed_pause_num == 0) {
gclog_or_tty->print_cr("none"); tty->print_cr("none");
} else { } else {
print_summary_sd(" Evacuation Pauses", &_total); print_summary_sd(" Evacuation Pauses", &_total);
print_summary(" Root Region Scan Wait", &_root_region_scan_wait); print_summary(" Root Region Scan Wait", &_root_region_scan_wait);
@ -2578,9 +2417,9 @@ void TraceYoungGenTimeData::print() const {
print_summary(" Clear CT", &_clear_ct); print_summary(" Clear CT", &_clear_ct);
print_summary(" Other", &_other); print_summary(" Other", &_other);
} }
gclog_or_tty->cr(); tty->cr();
gclog_or_tty->print_cr("MISC"); tty->print_cr("MISC");
print_summary_sd(" Stop World", &_all_stop_world_times_ms); print_summary_sd(" Stop World", &_all_stop_world_times_ms);
print_summary_sd(" Yields", &_all_yield_times_ms); print_summary_sd(" Yields", &_all_yield_times_ms);
} }
@ -2597,11 +2436,11 @@ void TraceOldGenTimeData::print() const {
} }
if (_all_full_gc_times.num() > 0) { if (_all_full_gc_times.num() > 0) {
gclog_or_tty->print("\n%4d full_gcs: total time = %8.2f s", tty->print("\n%4d full_gcs: total time = %8.2f s",
_all_full_gc_times.num(), _all_full_gc_times.num(),
_all_full_gc_times.sum() / 1000.0); _all_full_gc_times.sum() / 1000.0);
gclog_or_tty->print_cr(" (avg = %8.2fms).", _all_full_gc_times.avg()); tty->print_cr(" (avg = %8.2fms).", _all_full_gc_times.avg());
gclog_or_tty->print_cr(" [std. dev = %8.2f ms, max = %8.2f ms]", tty->print_cr(" [std. dev = %8.2f ms, max = %8.2f ms]",
_all_full_gc_times.sd(), _all_full_gc_times.sd(),
_all_full_gc_times.maximum()); _all_full_gc_times.maximum());
} }

View file

@ -159,6 +159,7 @@ public:
uint max_desired_young_length() { uint max_desired_young_length() {
return _max_desired_young_length; return _max_desired_young_length;
} }
bool adaptive_young_list_length() const { bool adaptive_young_list_length() const {
return _adaptive_size; return _adaptive_size;
} }
@ -658,9 +659,7 @@ public:
// Print heap sizing transition (with less and more detail). // Print heap sizing transition (with less and more detail).
void print_heap_transition(size_t bytes_before) const; void print_detailed_heap_transition() const;
void print_heap_transition() const;
void print_detailed_heap_transition(bool full = false) const;
virtual void print_phases(double pause_time_sec); virtual void print_phases(double pause_time_sec);
@ -827,6 +826,8 @@ private:
size_t _eden_used_bytes_before_gc; // Eden occupancy before GC size_t _eden_used_bytes_before_gc; // Eden occupancy before GC
size_t _survivor_used_bytes_before_gc; // Survivor occupancy before GC size_t _survivor_used_bytes_before_gc; // Survivor occupancy before GC
size_t _old_used_bytes_before_gc; // Old occupancy before GC
size_t _humongous_used_bytes_before_gc; // Humongous occupancy before GC
size_t _heap_used_bytes_before_gc; // Heap occupancy before GC size_t _heap_used_bytes_before_gc; // Heap occupancy before GC
size_t _metaspace_used_bytes_before_gc; // Metaspace occupancy before GC size_t _metaspace_used_bytes_before_gc; // Metaspace occupancy before GC

View file

@ -1,66 +0,0 @@
/*
* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "gc/g1/g1ErgoVerbose.hpp"
#include "utilities/ostream.hpp"
ErgoLevel G1ErgoVerbose::_level;
bool G1ErgoVerbose::_enabled[ErgoHeuristicNum];
void G1ErgoVerbose::initialize() {
set_level(ErgoLow);
set_enabled(false);
}
void G1ErgoVerbose::set_level(ErgoLevel level) {
_level = level;
}
void G1ErgoVerbose::set_enabled(ErgoHeuristic n, bool enabled) {
assert(0 <= n && n < ErgoHeuristicNum, "pre-condition");
_enabled[n] = enabled;
}
void G1ErgoVerbose::set_enabled(bool enabled) {
for (int n = 0; n < ErgoHeuristicNum; n += 1) {
set_enabled((ErgoHeuristic) n, enabled);
}
}
const char* G1ErgoVerbose::to_string(int tag) {
ErgoHeuristic n = extract_heuristic(tag);
switch (n) {
case ErgoHeapSizing: return "Heap Sizing";
case ErgoCSetConstruction: return "CSet Construction";
case ErgoConcCycles: return "Concurrent Cycles";
case ErgoMixedGCs: return "Mixed GCs";
case ErgoTiming: return "Timing";
case ErgoIHOP: return "IHOP";
default:
ShouldNotReachHere();
// Keep the Windows compiler happy
return NULL;
}
}

View file

@ -1,204 +0,0 @@
/*
* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_VM_GC_G1_G1ERGOVERBOSE_HPP
#define SHARE_VM_GC_G1_G1ERGOVERBOSE_HPP
#include "memory/allocation.hpp"
#include "utilities/debug.hpp"
// The log of G1's heuristic decisions comprises of a series of
// records which have a similar format in order to maintain
// consistency across records and ultimately easier parsing of the
// output, if we ever choose to do that. Each record consists of:
// * A time stamp to be able to easily correlate each record with
// other events.
// * A unique string to allow us to easily identify such records.
// * The name of the heuristic the record corresponds to.
// * An action string which describes the action that G1 did or is
// about to do.
// * An optional reason string which describes the reason for the
// action.
// * An optional number of name/value pairs which contributed to the
// decision to take the action described in the record.
//
// Each record is associated with a "tag" which is the combination of
// the heuristic the record corresponds to, as well as the min level
// of verboseness at which the record should be printed. The tag is
// checked against the current settings to determine whether the record
// should be printed or not.
// The available verboseness levels.
typedef enum {
// Determine which part of the tag is occupied by the level.
ErgoLevelShift = 8,
ErgoLevelMask = ~((1 << ErgoLevelShift) - 1),
// ErgoLow is 0 so that we don't have to explicitly or a heuristic
// id with ErgoLow to keep its use simpler.
ErgoLow = 0,
ErgoHigh = 1 << ErgoLevelShift
} ErgoLevel;
// The available heuristics.
typedef enum {
// Determines which part of the tag is occupied by the heuristic id.
ErgoHeuristicMask = ~ErgoLevelMask,
ErgoHeapSizing = 0,
ErgoCSetConstruction,
ErgoConcCycles,
ErgoMixedGCs,
ErgoTiming,
ErgoIHOP,
ErgoHeuristicNum
} ErgoHeuristic;
class G1ErgoVerbose : AllStatic {
private:
// Determines the minimum verboseness level at which records will be
// printed.
static ErgoLevel _level;
// Determines which heuristics are currently enabled.
static bool _enabled[ErgoHeuristicNum];
static ErgoLevel extract_level(int tag) {
return (ErgoLevel) (tag & ErgoLevelMask);
}
static ErgoHeuristic extract_heuristic(int tag) {
return (ErgoHeuristic) (tag & ErgoHeuristicMask);
}
public:
// Needs to be explicitly called at GC initialization.
static void initialize();
static void set_level(ErgoLevel level);
static void set_enabled(ErgoHeuristic h, bool enabled);
// It is applied to all heuristics.
static void set_enabled(bool enabled);
static bool enabled(int tag) {
ErgoLevel level = extract_level(tag);
ErgoHeuristic n = extract_heuristic(tag);
return level <= _level && _enabled[n];
}
// Extract the heuristic id from the tag and return a string with
// its name.
static const char* to_string(int tag);
};
// The macros below generate the format string for values of different
// types and/or metrics.
// The reason for the action is optional and is handled specially: the
// reason string is concatenated here so it's not necessary to pass it
// as a parameter.
#define ergo_format_reason(_reason_) ", reason: " _reason_
// Single parameter format strings
#define ergo_format_str(_name_) ", " _name_ ": %s"
#define ergo_format_region(_name_) ", " _name_ ": %u regions"
#define ergo_format_byte(_name_) ", " _name_ ": " SIZE_FORMAT " bytes"
#define ergo_format_double(_name_) ", " _name_ ": %1.2f"
#define ergo_format_perc(_name_) ", " _name_ ": %1.2f %%"
#define ergo_format_ms(_name_) ", " _name_ ": %1.2f ms"
#define ergo_format_size(_name_) ", " _name_ ": " SIZE_FORMAT
// Double parameter format strings
#define ergo_format_byte_perc(_name_) \
", " _name_ ": " SIZE_FORMAT " bytes (%1.2f %%)"
// Generates the format string
#define ergo_format(_extra_format_) \
" %1.3f: [G1Ergonomics (%s) %s" _extra_format_ "]"
// Conditionally, prints an ergonomic decision record. _extra_format_
// is the format string for the optional items we'd like to print
// (i.e., the decision's reason and any associated values). This
// string should be built up using the ergo_*_format macros (see
// above) to ensure consistency.
//
// Since we cannot rely on the compiler supporting variable argument
// macros, this macro accepts a fixed number of arguments and passes
// them to the print method. For convenience, we have wrapper macros
// below which take a specific number of arguments and set the rest to
// a default value.
#define ergo_verbose_common(_tag_, _action_, _extra_format_, \
_arg0_, _arg1_, _arg2_, _arg3_, _arg4_, _arg5_) \
do { \
if (G1ErgoVerbose::enabled((_tag_))) { \
gclog_or_tty->print_cr(ergo_format(_extra_format_), \
os::elapsedTime(), \
G1ErgoVerbose::to_string((_tag_)), \
(_action_), \
(_arg0_), (_arg1_), (_arg2_), \
(_arg3_), (_arg4_), (_arg5_)); \
} \
} while (0)
#define ergo_verbose6(_tag_, _action_, _extra_format_, \
_arg0_, _arg1_, _arg2_, _arg3_, _arg4_, _arg5_) \
ergo_verbose_common(_tag_, _action_, _extra_format_, \
_arg0_, _arg1_, _arg2_, _arg3_, _arg4_, _arg5_)
#define ergo_verbose5(_tag_, _action_, _extra_format_, \
_arg0_, _arg1_, _arg2_, _arg3_, _arg4_) \
ergo_verbose6(_tag_, _action_, _extra_format_ "%s", \
_arg0_, _arg1_, _arg2_, _arg3_, _arg4_, "")
#define ergo_verbose4(_tag_, _action_, _extra_format_, \
_arg0_, _arg1_, _arg2_, _arg3_) \
ergo_verbose5(_tag_, _action_, _extra_format_ "%s", \
_arg0_, _arg1_, _arg2_, _arg3_, "")
#define ergo_verbose3(_tag_, _action_, _extra_format_, \
_arg0_, _arg1_, _arg2_) \
ergo_verbose4(_tag_, _action_, _extra_format_ "%s", \
_arg0_, _arg1_, _arg2_, "")
#define ergo_verbose2(_tag_, _action_, _extra_format_, \
_arg0_, _arg1_) \
ergo_verbose3(_tag_, _action_, _extra_format_ "%s", \
_arg0_, _arg1_, "")
#define ergo_verbose1(_tag_, _action_, _extra_format_, \
_arg0_) \
ergo_verbose2(_tag_, _action_, _extra_format_ "%s", \
_arg0_, "")
#define ergo_verbose0(_tag_, _action_, _extra_format_) \
ergo_verbose1(_tag_, _action_, _extra_format_ "%s", \
"")
#define ergo_verbose(_tag_, _action_) \
ergo_verbose0(_tag_, _action_, "")
#endif // SHARE_VM_GC_G1_G1ERGOVERBOSE_HPP

View file

@ -26,91 +26,97 @@
#include "memory/allocation.inline.hpp" #include "memory/allocation.inline.hpp"
#include "gc/g1/g1EvacStats.hpp" #include "gc/g1/g1EvacStats.hpp"
#include "gc/shared/gcId.hpp" #include "gc/shared/gcId.hpp"
#include "logging/log.hpp"
#include "trace/tracing.hpp" #include "trace/tracing.hpp"
void G1EvacStats::adjust_desired_plab_sz() { void G1EvacStats::adjust_desired_plab_sz() {
if (PrintPLAB) { if (!ResizePLAB) {
gclog_or_tty->print(" (allocated = " SIZE_FORMAT " wasted = " SIZE_FORMAT " " log_debug(gc, plab)(" (allocated = " SIZE_FORMAT " wasted = " SIZE_FORMAT " "
"unused = " SIZE_FORMAT " used = " SIZE_FORMAT " " "unused = " SIZE_FORMAT " used = " SIZE_FORMAT " "
"undo_waste = " SIZE_FORMAT " region_end_waste = " SIZE_FORMAT " " "undo_waste = " SIZE_FORMAT " region_end_waste = " SIZE_FORMAT " "
"regions filled = %u direct_allocated = " SIZE_FORMAT " " "regions filled = %u direct_allocated = " SIZE_FORMAT " "
"failure_used = " SIZE_FORMAT " failure_waste = " SIZE_FORMAT ") ", "failure_used = " SIZE_FORMAT " failure_waste = " SIZE_FORMAT ") ",
_allocated, _wasted, _unused, used(), _undo_wasted, _region_end_waste, _allocated, _wasted, _unused, used(), _undo_wasted, _region_end_waste,
_regions_filled, _direct_allocated, _failure_used, _failure_waste); _regions_filled, _direct_allocated, _failure_used, _failure_waste);
// Clear accumulators for next round.
reset();
return;
} }
if (ResizePLAB) { assert(is_object_aligned(max_size()) && min_size() <= max_size(),
"PLAB clipping computation may be incorrect");
assert(is_object_aligned(max_size()) && min_size() <= max_size(), if (_allocated == 0) {
"PLAB clipping computation may be incorrect"); assert((_unused == 0),
"Inconsistency in PLAB stats: "
if (_allocated == 0) { "_allocated: " SIZE_FORMAT ", "
assert((_unused == 0), "_wasted: " SIZE_FORMAT ", "
"Inconsistency in PLAB stats: " "_region_end_waste: " SIZE_FORMAT ", "
"_allocated: " SIZE_FORMAT ", " "_unused: " SIZE_FORMAT ", "
"_wasted: " SIZE_FORMAT ", " "_used : " SIZE_FORMAT,
"_region_end_waste: " SIZE_FORMAT ", " _allocated, _wasted, _region_end_waste, _unused, used());
"_unused: " SIZE_FORMAT ", " _allocated = 1;
"_used : " SIZE_FORMAT,
_allocated, _wasted, _region_end_waste, _unused, used());
_allocated = 1;
}
// The size of the PLAB caps the amount of space that can be wasted at the
// end of the collection. In the worst case the last PLAB could be completely
// empty.
// This allows us to calculate the new PLAB size to achieve the
// TargetPLABWastePct given the latest memory usage and that the last buffer
// will be G1LastPLABAverageOccupancy full.
//
// E.g. assume that if in the current GC 100 words were allocated and a
// TargetPLABWastePct of 10 had been set.
//
// So we could waste up to 10 words to meet that percentage. Given that we
// also assume that that buffer is typically half-full, the new desired PLAB
// size is set to 20 words.
//
// The amount of allocation performed should be independent of the number of
// threads, so should the maximum waste we can spend in total. So if
// we used n threads to allocate, each of them can spend maximum waste/n words in
// a first rough approximation. The number of threads only comes into play later
// when actually retrieving the actual desired PLAB size.
//
// After calculating this optimal PLAB size the algorithm applies the usual
// exponential decaying average over this value to guess the next PLAB size.
//
// We account region end waste fully to PLAB allocation (in the calculation of
// what we consider as "used_for_waste_calculation" below). This is not
// completely fair, but is a conservative assumption because PLABs may be sized
// flexibly while we cannot adjust inline allocations.
// Allocation during GC will try to minimize region end waste so this impact
// should be minimal.
//
// We need to cover overflow when calculating the amount of space actually used
// by objects in PLABs when subtracting the region end waste.
// Region end waste may be higher than actual allocation. This may occur if many
// threads do not allocate anything but a few rather large objects. In this
// degenerate case the PLAB size would simply quickly tend to minimum PLAB size,
// which is an okay reaction.
size_t const used_for_waste_calculation = used() > _region_end_waste ? used() - _region_end_waste : 0;
size_t const total_waste_allowed = used_for_waste_calculation * TargetPLABWastePct;
size_t const cur_plab_sz = (size_t)((double)total_waste_allowed / G1LastPLABAverageOccupancy);
// Take historical weighted average
_filter.sample(cur_plab_sz);
// Clip from above and below, and align to object boundary
size_t plab_sz;
plab_sz = MAX2(min_size(), (size_t)_filter.average());
plab_sz = MIN2(max_size(), plab_sz);
plab_sz = align_object_size(plab_sz);
// Latch the result
_desired_net_plab_sz = plab_sz;
if (PrintPLAB) {
gclog_or_tty->print(" (plab_sz = " SIZE_FORMAT " desired_plab_sz = " SIZE_FORMAT ") ", cur_plab_sz, plab_sz);
}
}
if (PrintPLAB) {
gclog_or_tty->cr();
} }
// The size of the PLAB caps the amount of space that can be wasted at the
// end of the collection. In the worst case the last PLAB could be completely
// empty.
// This allows us to calculate the new PLAB size to achieve the
// TargetPLABWastePct given the latest memory usage and that the last buffer
// will be G1LastPLABAverageOccupancy full.
//
// E.g. assume that if in the current GC 100 words were allocated and a
// TargetPLABWastePct of 10 had been set.
//
// So we could waste up to 10 words to meet that percentage. Given that we
// also assume that that buffer is typically half-full, the new desired PLAB
// size is set to 20 words.
//
// The amount of allocation performed should be independent of the number of
// threads, so should the maximum waste we can spend in total. So if
// we used n threads to allocate, each of them can spend maximum waste/n words in
// a first rough approximation. The number of threads only comes into play later
// when actually retrieving the actual desired PLAB size.
//
// After calculating this optimal PLAB size the algorithm applies the usual
// exponential decaying average over this value to guess the next PLAB size.
//
// We account region end waste fully to PLAB allocation (in the calculation of
// what we consider as "used_for_waste_calculation" below). This is not
// completely fair, but is a conservative assumption because PLABs may be sized
// flexibly while we cannot adjust inline allocations.
// Allocation during GC will try to minimize region end waste so this impact
// should be minimal.
//
// We need to cover overflow when calculating the amount of space actually used
// by objects in PLABs when subtracting the region end waste.
// Region end waste may be higher than actual allocation. This may occur if many
// threads do not allocate anything but a few rather large objects. In this
// degenerate case the PLAB size would simply quickly tend to minimum PLAB size,
// which is an okay reaction.
size_t const used_for_waste_calculation = used() > _region_end_waste ? used() - _region_end_waste : 0;
size_t const total_waste_allowed = used_for_waste_calculation * TargetPLABWastePct;
size_t const cur_plab_sz = (size_t)((double)total_waste_allowed / G1LastPLABAverageOccupancy);
// Take historical weighted average
_filter.sample(cur_plab_sz);
// Clip from above and below, and align to object boundary
size_t plab_sz;
plab_sz = MAX2(min_size(), (size_t)_filter.average());
plab_sz = MIN2(max_size(), plab_sz);
plab_sz = align_object_size(plab_sz);
// Latch the result
_desired_net_plab_sz = plab_sz;
log_debug(gc, plab)(" (allocated = " SIZE_FORMAT " wasted = " SIZE_FORMAT " "
"unused = " SIZE_FORMAT " used = " SIZE_FORMAT " "
"undo_waste = " SIZE_FORMAT " region_end_waste = " SIZE_FORMAT " "
"regions filled = %u direct_allocated = " SIZE_FORMAT " "
"failure_used = " SIZE_FORMAT " failure_waste = " SIZE_FORMAT ") "
" (plab_sz = " SIZE_FORMAT " desired_plab_sz = " SIZE_FORMAT ")",
_allocated, _wasted, _unused, used(), _undo_wasted, _region_end_waste,
_regions_filled, _direct_allocated, _failure_used, _failure_waste,
cur_plab_sz, plab_sz);
// Clear accumulators for next round. // Clear accumulators for next round.
reset(); reset();
} }

View file

@ -26,10 +26,10 @@
#include "gc/g1/concurrentG1Refine.hpp" #include "gc/g1/concurrentG1Refine.hpp"
#include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp"
#include "gc/g1/g1GCPhaseTimes.hpp" #include "gc/g1/g1GCPhaseTimes.hpp"
#include "gc/g1/g1Log.hpp"
#include "gc/g1/g1StringDedup.hpp" #include "gc/g1/g1StringDedup.hpp"
#include "gc/g1/workerDataArray.inline.hpp" #include "gc/g1/workerDataArray.inline.hpp"
#include "memory/allocation.hpp" #include "memory/allocation.hpp"
#include "logging/log.hpp"
#include "runtime/os.hpp" #include "runtime/os.hpp"
// Helper class for avoiding interleaved logging // Helper class for avoiding interleaved logging
@ -73,66 +73,60 @@ public:
va_end(ap); va_end(ap);
} }
void print_cr() { const char* to_string() {
gclog_or_tty->print_cr("%s", _buffer);
_cur = _indent_level * INDENT_CHARS; _cur = _indent_level * INDENT_CHARS;
} return _buffer;
void append_and_print_cr(const char* format, ...) ATTRIBUTE_PRINTF(2, 3) {
va_list ap;
va_start(ap, format);
vappend(format, ap);
va_end(ap);
print_cr();
} }
}; };
static const char* Indents[4] = {"", " ", " ", " "};
G1GCPhaseTimes::G1GCPhaseTimes(uint max_gc_threads) : G1GCPhaseTimes::G1GCPhaseTimes(uint max_gc_threads) :
_max_gc_threads(max_gc_threads) _max_gc_threads(max_gc_threads)
{ {
assert(max_gc_threads > 0, "Must have some GC threads"); assert(max_gc_threads > 0, "Must have some GC threads");
_gc_par_phases[GCWorkerStart] = new WorkerDataArray<double>(max_gc_threads, "GC Worker Start (ms)", false, G1Log::LevelFiner, 2); _gc_par_phases[GCWorkerStart] = new WorkerDataArray<double>(max_gc_threads, "GC Worker Start:", false, 2);
_gc_par_phases[ExtRootScan] = new WorkerDataArray<double>(max_gc_threads, "Ext Root Scanning (ms)", true, G1Log::LevelFiner, 2); _gc_par_phases[ExtRootScan] = new WorkerDataArray<double>(max_gc_threads, "Ext Root Scanning:", true, 2);
// Root scanning phases // Root scanning phases
_gc_par_phases[ThreadRoots] = new WorkerDataArray<double>(max_gc_threads, "Thread Roots (ms)", true, G1Log::LevelFinest, 3); _gc_par_phases[ThreadRoots] = new WorkerDataArray<double>(max_gc_threads, "Thread Roots:", true, 3);
_gc_par_phases[StringTableRoots] = new WorkerDataArray<double>(max_gc_threads, "StringTable Roots (ms)", true, G1Log::LevelFinest, 3); _gc_par_phases[StringTableRoots] = new WorkerDataArray<double>(max_gc_threads, "StringTable Roots:", true, 3);
_gc_par_phases[UniverseRoots] = new WorkerDataArray<double>(max_gc_threads, "Universe Roots (ms)", true, G1Log::LevelFinest, 3); _gc_par_phases[UniverseRoots] = new WorkerDataArray<double>(max_gc_threads, "Universe Roots:", true, 3);
_gc_par_phases[JNIRoots] = new WorkerDataArray<double>(max_gc_threads, "JNI Handles Roots (ms)", true, G1Log::LevelFinest, 3); _gc_par_phases[JNIRoots] = new WorkerDataArray<double>(max_gc_threads, "JNI Handles Roots:", true, 3);
_gc_par_phases[ObjectSynchronizerRoots] = new WorkerDataArray<double>(max_gc_threads, "ObjectSynchronizer Roots (ms)", true, G1Log::LevelFinest, 3); _gc_par_phases[ObjectSynchronizerRoots] = new WorkerDataArray<double>(max_gc_threads, "ObjectSynchronizer Roots:", true, 3);
_gc_par_phases[FlatProfilerRoots] = new WorkerDataArray<double>(max_gc_threads, "FlatProfiler Roots (ms)", true, G1Log::LevelFinest, 3); _gc_par_phases[FlatProfilerRoots] = new WorkerDataArray<double>(max_gc_threads, "FlatProfiler Roots:", true, 3);
_gc_par_phases[ManagementRoots] = new WorkerDataArray<double>(max_gc_threads, "Management Roots (ms)", true, G1Log::LevelFinest, 3); _gc_par_phases[ManagementRoots] = new WorkerDataArray<double>(max_gc_threads, "Management Roots:", true, 3);
_gc_par_phases[SystemDictionaryRoots] = new WorkerDataArray<double>(max_gc_threads, "SystemDictionary Roots (ms)", true, G1Log::LevelFinest, 3); _gc_par_phases[SystemDictionaryRoots] = new WorkerDataArray<double>(max_gc_threads, "SystemDictionary Roots:", true, 3);
_gc_par_phases[CLDGRoots] = new WorkerDataArray<double>(max_gc_threads, "CLDG Roots (ms)", true, G1Log::LevelFinest, 3); _gc_par_phases[CLDGRoots] = new WorkerDataArray<double>(max_gc_threads, "CLDG Roots:", true, 3);
_gc_par_phases[JVMTIRoots] = new WorkerDataArray<double>(max_gc_threads, "JVMTI Roots (ms)", true, G1Log::LevelFinest, 3); _gc_par_phases[JVMTIRoots] = new WorkerDataArray<double>(max_gc_threads, "JVMTI Roots:", true, 3);
_gc_par_phases[CMRefRoots] = new WorkerDataArray<double>(max_gc_threads, "CM RefProcessor Roots (ms)", true, G1Log::LevelFinest, 3); _gc_par_phases[CMRefRoots] = new WorkerDataArray<double>(max_gc_threads, "CM RefProcessor Roots:", true, 3);
_gc_par_phases[WaitForStrongCLD] = new WorkerDataArray<double>(max_gc_threads, "Wait For Strong CLD (ms)", true, G1Log::LevelFinest, 3); _gc_par_phases[WaitForStrongCLD] = new WorkerDataArray<double>(max_gc_threads, "Wait For Strong CLD:", true, 3);
_gc_par_phases[WeakCLDRoots] = new WorkerDataArray<double>(max_gc_threads, "Weak CLD Roots (ms)", true, G1Log::LevelFinest, 3); _gc_par_phases[WeakCLDRoots] = new WorkerDataArray<double>(max_gc_threads, "Weak CLD Roots:", true, 3);
_gc_par_phases[SATBFiltering] = new WorkerDataArray<double>(max_gc_threads, "SATB Filtering (ms)", true, G1Log::LevelFinest, 3); _gc_par_phases[SATBFiltering] = new WorkerDataArray<double>(max_gc_threads, "SATB Filtering:", true, 3);
_gc_par_phases[UpdateRS] = new WorkerDataArray<double>(max_gc_threads, "Update RS (ms)", true, G1Log::LevelFiner, 2); _gc_par_phases[UpdateRS] = new WorkerDataArray<double>(max_gc_threads, "Update RS:", true, 2);
_gc_par_phases[ScanHCC] = new WorkerDataArray<double>(max_gc_threads, "Scan HCC (ms)", true, G1Log::LevelFiner, 3); _gc_par_phases[ScanHCC] = new WorkerDataArray<double>(max_gc_threads, "Scan HCC:", true, 3);
_gc_par_phases[ScanHCC]->set_enabled(ConcurrentG1Refine::hot_card_cache_enabled()); _gc_par_phases[ScanHCC]->set_enabled(ConcurrentG1Refine::hot_card_cache_enabled());
_gc_par_phases[ScanRS] = new WorkerDataArray<double>(max_gc_threads, "Scan RS (ms)", true, G1Log::LevelFiner, 2); _gc_par_phases[ScanRS] = new WorkerDataArray<double>(max_gc_threads, "Scan RS:", true, 2);
_gc_par_phases[CodeRoots] = new WorkerDataArray<double>(max_gc_threads, "Code Root Scanning (ms)", true, G1Log::LevelFiner, 2); _gc_par_phases[CodeRoots] = new WorkerDataArray<double>(max_gc_threads, "Code Root Scanning:", true, 2);
_gc_par_phases[ObjCopy] = new WorkerDataArray<double>(max_gc_threads, "Object Copy (ms)", true, G1Log::LevelFiner, 2); _gc_par_phases[ObjCopy] = new WorkerDataArray<double>(max_gc_threads, "Object Copy:", true, 2);
_gc_par_phases[Termination] = new WorkerDataArray<double>(max_gc_threads, "Termination (ms)", true, G1Log::LevelFiner, 2); _gc_par_phases[Termination] = new WorkerDataArray<double>(max_gc_threads, "Termination:", true, 2);
_gc_par_phases[GCWorkerTotal] = new WorkerDataArray<double>(max_gc_threads, "GC Worker Total (ms)", true, G1Log::LevelFiner, 2); _gc_par_phases[GCWorkerTotal] = new WorkerDataArray<double>(max_gc_threads, "GC Worker Total:", true, 2);
_gc_par_phases[GCWorkerEnd] = new WorkerDataArray<double>(max_gc_threads, "GC Worker End (ms)", false, G1Log::LevelFiner, 2); _gc_par_phases[GCWorkerEnd] = new WorkerDataArray<double>(max_gc_threads, "GC Worker End:", false, 2);
_gc_par_phases[Other] = new WorkerDataArray<double>(max_gc_threads, "GC Worker Other (ms)", true, G1Log::LevelFiner, 2); _gc_par_phases[Other] = new WorkerDataArray<double>(max_gc_threads, "GC Worker Other:", true, 2);
_update_rs_processed_buffers = new WorkerDataArray<size_t>(max_gc_threads, "Processed Buffers", true, G1Log::LevelFiner, 3); _update_rs_processed_buffers = new WorkerDataArray<size_t>(max_gc_threads, "Processed Buffers:", true, 3);
_gc_par_phases[UpdateRS]->link_thread_work_items(_update_rs_processed_buffers); _gc_par_phases[UpdateRS]->link_thread_work_items(_update_rs_processed_buffers);
_termination_attempts = new WorkerDataArray<size_t>(max_gc_threads, "Termination Attempts", true, G1Log::LevelFinest, 3); _termination_attempts = new WorkerDataArray<size_t>(max_gc_threads, "Termination Attempts:", true, 3);
_gc_par_phases[Termination]->link_thread_work_items(_termination_attempts); _gc_par_phases[Termination]->link_thread_work_items(_termination_attempts);
_gc_par_phases[StringDedupQueueFixup] = new WorkerDataArray<double>(max_gc_threads, "Queue Fixup (ms)", true, G1Log::LevelFiner, 2); _gc_par_phases[StringDedupQueueFixup] = new WorkerDataArray<double>(max_gc_threads, "Queue Fixup:", true, 2);
_gc_par_phases[StringDedupTableFixup] = new WorkerDataArray<double>(max_gc_threads, "Table Fixup (ms)", true, G1Log::LevelFiner, 2); _gc_par_phases[StringDedupTableFixup] = new WorkerDataArray<double>(max_gc_threads, "Table Fixup:", true, 2);
_gc_par_phases[RedirtyCards] = new WorkerDataArray<double>(max_gc_threads, "Parallel Redirty", true, G1Log::LevelFinest, 3); _gc_par_phases[RedirtyCards] = new WorkerDataArray<double>(max_gc_threads, "Parallel Redirty", true, 3);
_redirtied_cards = new WorkerDataArray<size_t>(max_gc_threads, "Redirtied Cards", true, G1Log::LevelFinest, 3); _redirtied_cards = new WorkerDataArray<size_t>(max_gc_threads, "Redirtied Cards:", true, 3);
_gc_par_phases[RedirtyCards]->link_thread_work_items(_redirtied_cards); _gc_par_phases[RedirtyCards]->link_thread_work_items(_redirtied_cards);
} }
@ -173,16 +167,8 @@ void G1GCPhaseTimes::note_gc_end() {
} }
} }
void G1GCPhaseTimes::print_stats(int level, const char* str, double value) { void G1GCPhaseTimes::print_stats(const char* indent, const char* str, double value) {
LineBuffer(level).append_and_print_cr("[%s: %.1lf ms]", str, value); log_debug(gc, phases)("%s%s: %.1lf ms", indent, str, value);
}
void G1GCPhaseTimes::print_stats(int level, const char* str, size_t value) {
LineBuffer(level).append_and_print_cr("[%s: " SIZE_FORMAT "]", str, value);
}
void G1GCPhaseTimes::print_stats(int level, const char* str, double value, uint workers) {
LineBuffer(level).append_and_print_cr("[%s: %.1lf ms, GC Workers: %u]", str, value, workers);
} }
double G1GCPhaseTimes::accounted_time_ms() { double G1GCPhaseTimes::accounted_time_ms() {
@ -284,10 +270,6 @@ class G1GCParPhasePrinter : public StackObj {
void print(G1GCPhaseTimes::GCParPhases phase_id) { void print(G1GCPhaseTimes::GCParPhases phase_id) {
WorkerDataArray<double>* phase = _phase_times->_gc_par_phases[phase_id]; WorkerDataArray<double>* phase = _phase_times->_gc_par_phases[phase_id];
if (phase->_log_level > G1Log::level() || !phase->_enabled) {
return;
}
if (phase->_length == 1) { if (phase->_length == 1) {
print_single_length(phase_id, phase); print_single_length(phase_id, phase);
} else { } else {
@ -295,69 +277,71 @@ class G1GCParPhasePrinter : public StackObj {
} }
} }
private:
private:
void print_single_length(G1GCPhaseTimes::GCParPhases phase_id, WorkerDataArray<double>* phase) { void print_single_length(G1GCPhaseTimes::GCParPhases phase_id, WorkerDataArray<double>* phase) {
// No need for min, max, average and sum for only one worker // No need for min, max, average and sum for only one worker
LineBuffer buf(phase->_indent_level); log_debug(gc, phases)("%s%s: %.1lf", Indents[phase->_indent_level], phase->_title, _phase_times->get_time_ms(phase_id, 0));
buf.append_and_print_cr("[%s: %.1lf]", phase->_title, _phase_times->get_time_ms(phase_id, 0));
if (phase->_thread_work_items != NULL) { WorkerDataArray<size_t>* work_items = phase->_thread_work_items;
LineBuffer buf2(phase->_thread_work_items->_indent_level); if (work_items != NULL) {
buf2.append_and_print_cr("[%s: " SIZE_FORMAT "]", phase->_thread_work_items->_title, _phase_times->sum_thread_work_items(phase_id)); log_debug(gc, phases)("%s%s: " SIZE_FORMAT, Indents[work_items->_indent_level], work_items->_title, _phase_times->sum_thread_work_items(phase_id));
} }
} }
void print_time_values(LineBuffer& buf, G1GCPhaseTimes::GCParPhases phase_id, WorkerDataArray<double>* phase) { void print_time_values(const char* indent, G1GCPhaseTimes::GCParPhases phase_id) {
uint active_length = _phase_times->_active_gc_threads; if (log_is_enabled(Trace, gc)) {
for (uint i = 0; i < active_length; ++i) { LineBuffer buf(0);
buf.append(" %.1lf", _phase_times->get_time_ms(phase_id, i)); uint active_length = _phase_times->_active_gc_threads;
for (uint i = 0; i < active_length; ++i) {
buf.append(" %4.1lf", _phase_times->get_time_ms(phase_id, i));
}
const char* line = buf.to_string();
log_trace(gc, phases)("%s%-25s%s", indent, "", line);
} }
buf.print_cr();
} }
void print_count_values(LineBuffer& buf, G1GCPhaseTimes::GCParPhases phase_id, WorkerDataArray<size_t>* thread_work_items) { void print_count_values(const char* indent, G1GCPhaseTimes::GCParPhases phase_id, WorkerDataArray<size_t>* thread_work_items) {
uint active_length = _phase_times->_active_gc_threads; if (log_is_enabled(Trace, gc)) {
for (uint i = 0; i < active_length; ++i) { LineBuffer buf(0);
buf.append(" " SIZE_FORMAT, _phase_times->get_thread_work_item(phase_id, i)); uint active_length = _phase_times->_active_gc_threads;
for (uint i = 0; i < active_length; ++i) {
buf.append(" " SIZE_FORMAT, _phase_times->get_thread_work_item(phase_id, i));
}
const char* line = buf.to_string();
log_trace(gc, phases)("%s%-25s%s", indent, "", line);
} }
buf.print_cr();
} }
void print_thread_work_items(G1GCPhaseTimes::GCParPhases phase_id, WorkerDataArray<size_t>* thread_work_items) { void print_thread_work_items(G1GCPhaseTimes::GCParPhases phase_id, WorkerDataArray<size_t>* thread_work_items) {
LineBuffer buf(thread_work_items->_indent_level); const char* indent = Indents[thread_work_items->_indent_level];
buf.append("[%s:", thread_work_items->_title);
if (G1Log::finest()) {
print_count_values(buf, phase_id, thread_work_items);
}
assert(thread_work_items->_print_sum, "%s does not have print sum true even though it is a count", thread_work_items->_title); assert(thread_work_items->_print_sum, "%s does not have print sum true even though it is a count", thread_work_items->_title);
buf.append_and_print_cr(" Min: " SIZE_FORMAT ", Avg: %.1lf, Max: " SIZE_FORMAT ", Diff: " SIZE_FORMAT ", Sum: " SIZE_FORMAT "]", log_debug(gc, phases)("%s%-25s Min: " SIZE_FORMAT ", Avg: %4.1lf, Max: " SIZE_FORMAT ", Diff: " SIZE_FORMAT ", Sum: " SIZE_FORMAT,
indent, thread_work_items->_title,
_phase_times->min_thread_work_items(phase_id), _phase_times->average_thread_work_items(phase_id), _phase_times->max_thread_work_items(phase_id), _phase_times->min_thread_work_items(phase_id), _phase_times->average_thread_work_items(phase_id), _phase_times->max_thread_work_items(phase_id),
_phase_times->max_thread_work_items(phase_id) - _phase_times->min_thread_work_items(phase_id), _phase_times->sum_thread_work_items(phase_id)); _phase_times->max_thread_work_items(phase_id) - _phase_times->min_thread_work_items(phase_id), _phase_times->sum_thread_work_items(phase_id));
print_count_values(indent, phase_id, thread_work_items);
} }
void print_multi_length(G1GCPhaseTimes::GCParPhases phase_id, WorkerDataArray<double>* phase) { void print_multi_length(G1GCPhaseTimes::GCParPhases phase_id, WorkerDataArray<double>* phase) {
LineBuffer buf(phase->_indent_level); const char* indent = Indents[phase->_indent_level];
buf.append("[%s:", phase->_title);
if (G1Log::finest()) {
print_time_values(buf, phase_id, phase);
}
buf.append(" Min: %.1lf, Avg: %.1lf, Max: %.1lf, Diff: %.1lf",
_phase_times->min_time_ms(phase_id), _phase_times->average_time_ms(phase_id), _phase_times->max_time_ms(phase_id),
_phase_times->max_time_ms(phase_id) - _phase_times->min_time_ms(phase_id));
if (phase->_print_sum) { if (phase->_print_sum) {
// for things like the start and end times the sum is not log_debug(gc, phases)("%s%-25s Min: %4.1lf, Avg: %4.1lf, Max: %4.1lf, Diff: %4.1lf, Sum: %4.1lf",
// that relevant indent, phase->_title,
buf.append(", Sum: %.1lf", _phase_times->sum_time_ms(phase_id)); _phase_times->min_time_ms(phase_id), _phase_times->average_time_ms(phase_id), _phase_times->max_time_ms(phase_id),
_phase_times->max_time_ms(phase_id) - _phase_times->min_time_ms(phase_id), _phase_times->sum_time_ms(phase_id));
} else {
log_debug(gc, phases)("%s%-25s Min: %4.1lf, Avg: %4.1lf, Max: %4.1lf, Diff: %4.1lf",
indent, phase->_title,
_phase_times->min_time_ms(phase_id), _phase_times->average_time_ms(phase_id), _phase_times->max_time_ms(phase_id),
_phase_times->max_time_ms(phase_id) - _phase_times->min_time_ms(phase_id));
} }
buf.append_and_print_cr("]"); print_time_values(indent, phase_id);
if (phase->_thread_work_items != NULL) { if (phase->_thread_work_items != NULL) {
print_thread_work_items(phase_id, phase->_thread_work_items); print_thread_work_items(phase_id, phase->_thread_work_items);
@ -371,67 +355,59 @@ void G1GCPhaseTimes::print(double pause_time_sec) {
G1GCParPhasePrinter par_phase_printer(this); G1GCParPhasePrinter par_phase_printer(this);
if (_root_region_scan_wait_time_ms > 0.0) { if (_root_region_scan_wait_time_ms > 0.0) {
print_stats(1, "Root Region Scan Waiting", _root_region_scan_wait_time_ms); print_stats(Indents[1], "Root Region Scan Waiting", _root_region_scan_wait_time_ms);
} }
print_stats(1, "Parallel Time", _cur_collection_par_time_ms, _active_gc_threads); print_stats(Indents[1], "Parallel Time", _cur_collection_par_time_ms);
for (int i = 0; i <= GCMainParPhasesLast; i++) { for (int i = 0; i <= GCMainParPhasesLast; i++) {
par_phase_printer.print((GCParPhases) i); par_phase_printer.print((GCParPhases) i);
} }
print_stats(1, "Code Root Fixup", _cur_collection_code_root_fixup_time_ms); print_stats(Indents[1], "Code Root Fixup", _cur_collection_code_root_fixup_time_ms);
print_stats(1, "Code Root Purge", _cur_strong_code_root_purge_time_ms); print_stats(Indents[1], "Code Root Purge", _cur_strong_code_root_purge_time_ms);
if (G1StringDedup::is_enabled()) { if (G1StringDedup::is_enabled()) {
print_stats(1, "String Dedup Fixup", _cur_string_dedup_fixup_time_ms, _active_gc_threads); print_stats(Indents[1], "String Dedup Fixup", _cur_string_dedup_fixup_time_ms);
for (int i = StringDedupPhasesFirst; i <= StringDedupPhasesLast; i++) { for (int i = StringDedupPhasesFirst; i <= StringDedupPhasesLast; i++) {
par_phase_printer.print((GCParPhases) i); par_phase_printer.print((GCParPhases) i);
} }
} }
print_stats(1, "Clear CT", _cur_clear_ct_time_ms); print_stats(Indents[1], "Clear CT", _cur_clear_ct_time_ms);
print_stats(1, "Expand Heap After Collection", _cur_expand_heap_time_ms); print_stats(Indents[1], "Expand Heap After Collection", _cur_expand_heap_time_ms);
double misc_time_ms = pause_time_sec * MILLIUNITS - accounted_time_ms(); double misc_time_ms = pause_time_sec * MILLIUNITS - accounted_time_ms();
print_stats(1, "Other", misc_time_ms); print_stats(Indents[1], "Other", misc_time_ms);
if (_cur_verify_before_time_ms > 0.0) { if (_cur_verify_before_time_ms > 0.0) {
print_stats(2, "Verify Before", _cur_verify_before_time_ms); print_stats(Indents[2], "Verify Before", _cur_verify_before_time_ms);
} }
if (G1CollectedHeap::heap()->evacuation_failed()) { if (G1CollectedHeap::heap()->evacuation_failed()) {
double evac_fail_handling = _cur_evac_fail_recalc_used + _cur_evac_fail_remove_self_forwards + double evac_fail_handling = _cur_evac_fail_recalc_used + _cur_evac_fail_remove_self_forwards +
_cur_evac_fail_restore_remsets; _cur_evac_fail_restore_remsets;
print_stats(2, "Evacuation Failure", evac_fail_handling); print_stats(Indents[2], "Evacuation Failure", evac_fail_handling);
if (G1Log::finest()) { log_trace(gc, phases)("%sRecalculate Used: %.1lf ms", Indents[3], _cur_evac_fail_recalc_used);
print_stats(3, "Recalculate Used", _cur_evac_fail_recalc_used); log_trace(gc, phases)("%sRemove Self Forwards: %.1lf ms", Indents[3], _cur_evac_fail_remove_self_forwards);
print_stats(3, "Remove Self Forwards", _cur_evac_fail_remove_self_forwards); log_trace(gc, phases)("%sRestore RemSet: %.1lf ms", Indents[3], _cur_evac_fail_restore_remsets);
print_stats(3, "Restore RemSet", _cur_evac_fail_restore_remsets);
}
} }
print_stats(2, "Choose CSet", print_stats(Indents[2], "Choose CSet",
(_recorded_young_cset_choice_time_ms + (_recorded_young_cset_choice_time_ms +
_recorded_non_young_cset_choice_time_ms)); _recorded_non_young_cset_choice_time_ms));
print_stats(2, "Ref Proc", _cur_ref_proc_time_ms); print_stats(Indents[2], "Ref Proc", _cur_ref_proc_time_ms);
print_stats(2, "Ref Enq", _cur_ref_enq_time_ms); print_stats(Indents[2], "Ref Enq", _cur_ref_enq_time_ms);
print_stats(2, "Redirty Cards", _recorded_redirty_logged_cards_time_ms); print_stats(Indents[2], "Redirty Cards", _recorded_redirty_logged_cards_time_ms);
par_phase_printer.print(RedirtyCards); par_phase_printer.print(RedirtyCards);
if (G1EagerReclaimHumongousObjects) { if (G1EagerReclaimHumongousObjects) {
print_stats(2, "Humongous Register", _cur_fast_reclaim_humongous_register_time_ms); print_stats(Indents[2], "Humongous Register", _cur_fast_reclaim_humongous_register_time_ms);
if (G1Log::finest()) {
print_stats(3, "Humongous Total", _cur_fast_reclaim_humongous_total); log_trace(gc, phases)("%sHumongous Total: " SIZE_FORMAT, Indents[3], _cur_fast_reclaim_humongous_total);
print_stats(3, "Humongous Candidate", _cur_fast_reclaim_humongous_candidates); log_trace(gc, phases)("%sHumongous Candidate: " SIZE_FORMAT, Indents[3], _cur_fast_reclaim_humongous_candidates);
} print_stats(Indents[2], "Humongous Reclaim", _cur_fast_reclaim_humongous_time_ms);
print_stats(2, "Humongous Reclaim", _cur_fast_reclaim_humongous_time_ms); log_trace(gc, phases)("%sHumongous Reclaimed: " SIZE_FORMAT, Indents[3], _cur_fast_reclaim_humongous_reclaimed);
if (G1Log::finest()) {
print_stats(3, "Humongous Reclaimed", _cur_fast_reclaim_humongous_reclaimed);
}
} }
print_stats(2, "Free CSet", print_stats(Indents[2], "Free CSet",
(_recorded_young_free_cset_time_ms + (_recorded_young_free_cset_time_ms +
_recorded_non_young_free_cset_time_ms)); _recorded_non_young_free_cset_time_ms));
if (G1Log::finest()) { log_trace(gc, phases)("%sYoung Free CSet: %.1lf ms", Indents[3], _recorded_young_free_cset_time_ms);
print_stats(3, "Young Free CSet", _recorded_young_free_cset_time_ms); log_trace(gc, phases)("%sNon-Young Free CSet: %.1lf ms", Indents[3], _recorded_non_young_free_cset_time_ms);
print_stats(3, "Non-Young Free CSet", _recorded_non_young_free_cset_time_ms);
}
if (_cur_verify_after_time_ms > 0.0) { if (_cur_verify_after_time_ms > 0.0) {
print_stats(2, "Verify After", _cur_verify_after_time_ms); print_stats(Indents[2], "Verify After", _cur_verify_after_time_ms);
} }
} }

View file

@ -119,9 +119,7 @@ class G1GCPhaseTimes : public CHeapObj<mtGC> {
double _cur_verify_after_time_ms; double _cur_verify_after_time_ms;
// Helper methods for detailed logging // Helper methods for detailed logging
void print_stats(int level, const char* str, double value); void print_stats(const char*, const char* str, double value);
void print_stats(int level, const char* str, size_t value);
void print_stats(int level, const char* str, double value, uint workers);
void note_gc_end(); void note_gc_end();

View file

@ -60,18 +60,6 @@ const char* G1HRPrinter::region_type_name(RegionType type) {
return NULL; return NULL;
} }
const char* G1HRPrinter::phase_name(PhaseType phase) {
switch (phase) {
case StartGC: return "StartGC";
case EndGC: return "EndGC";
case StartFullGC: return "StartFullGC";
case EndFullGC: return "EndFullGC";
default: ShouldNotReachHere();
}
// trying to keep the Windows compiler happy
return NULL;
}
#define G1HR_PREFIX " G1HR" #define G1HR_PREFIX " G1HR"
void G1HRPrinter::print(ActionType action, RegionType type, void G1HRPrinter::print(ActionType action, RegionType type,
@ -82,19 +70,19 @@ void G1HRPrinter::print(ActionType action, RegionType type,
if (type_str != NULL) { if (type_str != NULL) {
if (top != NULL) { if (top != NULL) {
gclog_or_tty->print_cr(G1HR_PREFIX " %s(%s) " PTR_FORMAT " " PTR_FORMAT, log_trace(gc, region)(G1HR_PREFIX " %s(%s) " PTR_FORMAT " " PTR_FORMAT,
action_str, type_str, p2i(bottom), p2i(top)); action_str, type_str, p2i(bottom), p2i(top));
} else { } else {
gclog_or_tty->print_cr(G1HR_PREFIX " %s(%s) " PTR_FORMAT, log_trace(gc, region)(G1HR_PREFIX " %s(%s) " PTR_FORMAT,
action_str, type_str, p2i(bottom)); action_str, type_str, p2i(bottom));
} }
} else { } else {
if (top != NULL) { if (top != NULL) {
gclog_or_tty->print_cr(G1HR_PREFIX " %s " PTR_FORMAT " " PTR_FORMAT, log_trace(gc, region)(G1HR_PREFIX " %s " PTR_FORMAT " " PTR_FORMAT,
action_str, p2i(bottom), p2i(top)); action_str, p2i(bottom), p2i(top));
} else { } else {
gclog_or_tty->print_cr(G1HR_PREFIX " %s " PTR_FORMAT, log_trace(gc, region)(G1HR_PREFIX " %s " PTR_FORMAT,
action_str, p2i(bottom)); action_str, p2i(bottom));
} }
} }
} }
@ -102,11 +90,6 @@ void G1HRPrinter::print(ActionType action, RegionType type,
void G1HRPrinter::print(ActionType action, HeapWord* bottom, HeapWord* end) { void G1HRPrinter::print(ActionType action, HeapWord* bottom, HeapWord* end) {
const char* action_str = action_name(action); const char* action_str = action_name(action);
gclog_or_tty->print_cr(G1HR_PREFIX " %s [" PTR_FORMAT "," PTR_FORMAT "]", log_trace(gc, region)(G1HR_PREFIX " %s [" PTR_FORMAT "," PTR_FORMAT "]",
action_str, p2i(bottom), p2i(end)); action_str, p2i(bottom), p2i(end));
}
void G1HRPrinter::print(PhaseType phase, size_t phase_num) {
const char* phase_str = phase_name(phase);
gclog_or_tty->print_cr(G1HR_PREFIX " #%s " SIZE_FORMAT, phase_str, phase_num);
} }

View file

@ -26,6 +26,7 @@
#define SHARE_VM_GC_G1_G1HRPRINTER_HPP #define SHARE_VM_GC_G1_G1HRPRINTER_HPP
#include "gc/g1/heapRegion.hpp" #include "gc/g1/heapRegion.hpp"
#include "logging/log.hpp"
#include "memory/allocation.hpp" #include "memory/allocation.hpp"
#define SKIP_RETIRED_FULL_REGIONS 1 #define SKIP_RETIRED_FULL_REGIONS 1
@ -55,19 +56,9 @@ public:
Archive Archive
} RegionType; } RegionType;
typedef enum {
StartGC,
EndGC,
StartFullGC,
EndFullGC
} PhaseType;
private: private:
bool _active;
static const char* action_name(ActionType action); static const char* action_name(ActionType action);
static const char* region_type_name(RegionType type); static const char* region_type_name(RegionType type);
static const char* phase_name(PhaseType phase);
// Print an action event. This version is used in most scenarios and // Print an action event. This version is used in most scenarios and
// only prints the region's bottom. The parameters type and top are // only prints the region's bottom. The parameters type and top are
@ -79,18 +70,11 @@ private:
// bottom and end. Used for Commit / Uncommit events. // bottom and end. Used for Commit / Uncommit events.
static void print(ActionType action, HeapWord* bottom, HeapWord* end); static void print(ActionType action, HeapWord* bottom, HeapWord* end);
// Print a phase event.
static void print(PhaseType phase, size_t phase_num);
public: public:
// In some places we iterate over a list in order to generate output // In some places we iterate over a list in order to generate output
// for the list's elements. By exposing this we can avoid this // for the list's elements. By exposing this we can avoid this
// iteration if the printer is not active. // iteration if the printer is not active.
const bool is_active() { return _active; } const bool is_active() { return log_is_enabled(Trace, gc, region); }
// Have to set this explicitly as we have to do this during the
// heap's initialize() method, not in the constructor.
void set_active(bool active) { _active = active; }
// The methods below are convenient wrappers for the print() methods. // The methods below are convenient wrappers for the print() methods.
@ -155,28 +139,6 @@ public:
print(Uncommit, bottom, end); print(Uncommit, bottom, end);
} }
} }
void start_gc(bool full, size_t gc_num) {
if (is_active()) {
if (!full) {
print(StartGC, gc_num);
} else {
print(StartFullGC, gc_num);
}
}
}
void end_gc(bool full, size_t gc_num) {
if (is_active()) {
if (!full) {
print(EndGC, gc_num);
} else {
print(EndFullGC, gc_num);
}
}
}
G1HRPrinter() : _active(false) { }
}; };
#endif // SHARE_VM_GC_G1_G1HRPRINTER_HPP #endif // SHARE_VM_GC_G1_G1HRPRINTER_HPP

View file

@ -24,10 +24,10 @@
#include "precompiled.hpp" #include "precompiled.hpp"
#include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp"
#include "gc/g1/g1ErgoVerbose.hpp"
#include "gc/g1/g1IHOPControl.hpp" #include "gc/g1/g1IHOPControl.hpp"
#include "gc/g1/g1Predictions.hpp" #include "gc/g1/g1Predictions.hpp"
#include "gc/shared/gcTrace.hpp" #include "gc/shared/gcTrace.hpp"
#include "logging/log.hpp"
G1IHOPControl::G1IHOPControl(double initial_ihop_percent, size_t target_occupancy) : G1IHOPControl::G1IHOPControl(double initial_ihop_percent, size_t target_occupancy) :
_initial_ihop_percent(initial_ihop_percent), _initial_ihop_percent(initial_ihop_percent),
@ -47,20 +47,14 @@ void G1IHOPControl::update_allocation_info(double allocation_time_s, size_t allo
void G1IHOPControl::print() { void G1IHOPControl::print() {
size_t cur_conc_mark_start_threshold = get_conc_mark_start_threshold(); size_t cur_conc_mark_start_threshold = get_conc_mark_start_threshold();
ergo_verbose6(ErgoIHOP, log_debug(gc, ihop)("Basic information (value update), threshold: " SIZE_FORMAT "B (%1.2f), target occupancy: " SIZE_FORMAT "B, current occupancy: " SIZE_FORMAT "B,"
"basic information", " recent old gen allocation rate: %1.2f, recent marking phase length: %1.2f",
ergo_format_reason("value update") cur_conc_mark_start_threshold,
ergo_format_byte_perc("threshold") cur_conc_mark_start_threshold * 100.0 / _target_occupancy,
ergo_format_byte("target occupancy") _target_occupancy,
ergo_format_byte("current occupancy") G1CollectedHeap::heap()->used(),
ergo_format_double("recent old gen allocation rate") _last_allocation_time_s > 0.0 ? _last_allocated_bytes / _last_allocation_time_s : 0.0,
ergo_format_double("recent marking phase length"), last_marking_length_s());
cur_conc_mark_start_threshold,
cur_conc_mark_start_threshold * 100.0 / _target_occupancy,
_target_occupancy,
G1CollectedHeap::heap()->used(),
_last_allocation_time_s > 0.0 ? _last_allocated_bytes / _last_allocation_time_s : 0.0,
last_marking_length_s());
} }
void G1IHOPControl::send_trace_event(G1NewTracer* tracer) { void G1IHOPControl::send_trace_event(G1NewTracer* tracer) {
@ -192,21 +186,14 @@ void G1AdaptiveIHOPControl::update_marking_length(double marking_length_s) {
void G1AdaptiveIHOPControl::print() { void G1AdaptiveIHOPControl::print() {
G1IHOPControl::print(); G1IHOPControl::print();
size_t actual_target = actual_target_threshold(); size_t actual_target = actual_target_threshold();
ergo_verbose6(ErgoIHOP, log_debug(gc, ihop)("Adaptive IHOP information (value update), threshold: " SIZE_FORMAT "B (%1.2f), internal target occupancy: " SIZE_FORMAT "B,"
"adaptive IHOP information", " predicted old gen allocation rate: %1.2f, predicted marking phase length: %1.2f, prediction active: %s",
ergo_format_reason("value update") get_conc_mark_start_threshold(),
ergo_format_byte_perc("threshold") percent_of(get_conc_mark_start_threshold(), actual_target),
ergo_format_byte("internal target occupancy") actual_target,
ergo_format_double("predicted old gen allocation rate") _predictor->get_new_prediction(&_allocation_rate_s),
ergo_format_double("predicted marking phase length") _predictor->get_new_prediction(&_marking_times_s),
ergo_format_str("prediction active"), have_enough_data_for_prediction() ? "true" : "false");
get_conc_mark_start_threshold(),
percent_of(get_conc_mark_start_threshold(), actual_target),
actual_target,
_predictor->get_new_prediction(&_allocation_rate_s),
_predictor->get_new_prediction(&_marking_times_s),
have_enough_data_for_prediction() ? "true" : "false"
);
} }
void G1AdaptiveIHOPControl::send_trace_event(G1NewTracer* tracer) { void G1AdaptiveIHOPControl::send_trace_event(G1NewTracer* tracer) {

View file

@ -1,70 +0,0 @@
/*
* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "gc/g1/g1Log.hpp"
#include "gc/g1/g1_globals.hpp"
#include "runtime/globals_extension.hpp"
G1Log::LogLevel G1Log::_level = G1Log::LevelNone;
// Updates _level based on PrintGC and PrintGCDetails values (unless
// G1LogLevel is set explicitly)
// - PrintGC maps to "fine".
// - PrintGCDetails maps to "finer".
void G1Log::update_level() {
if (FLAG_IS_DEFAULT(G1LogLevel)) {
_level = LevelNone;
if (PrintGCDetails) {
_level = LevelFiner;
} else if (PrintGC) {
_level = LevelFine;
}
}
}
// If G1LogLevel has not been set up we will use the values of PrintGC
// and PrintGCDetails for the logging level.
void G1Log::init() {
if (!FLAG_IS_DEFAULT(G1LogLevel)) {
// PrintGC flags change won't have any affect, because G1LogLevel
// is set explicitly
if (G1LogLevel[0] == '\0' || strncmp("none", G1LogLevel, 4) == 0 && G1LogLevel[4] == '\0') {
_level = LevelNone;
} else if (strncmp("fine", G1LogLevel, 4) == 0 && G1LogLevel[4] == '\0') {
_level = LevelFine;
} else if (strncmp("finer", G1LogLevel, 5) == 0 && G1LogLevel[5] == '\0') {
_level = LevelFiner;
} else if (strncmp("finest", G1LogLevel, 6) == 0 && G1LogLevel[6] == '\0') {
_level = LevelFinest;
} else {
warning("Unknown logging level '%s', should be one of 'fine', 'finer' or 'finest'.", G1LogLevel);
}
} else {
update_level();
}
}

View file

@ -1,65 +0,0 @@
/*
* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_VM_GC_G1_G1LOG_HPP
#define SHARE_VM_GC_G1_G1LOG_HPP
#include "memory/allocation.hpp"
class G1Log : public AllStatic {
public:
typedef enum {
LevelNone,
LevelFine,
LevelFiner,
LevelFinest
} LogLevel;
private:
static LogLevel _level;
public:
inline static bool fine() {
return _level >= LevelFine;
}
inline static bool finer() {
return _level >= LevelFiner;
}
inline static bool finest() {
return _level == LevelFinest;
}
static LogLevel level() {
return _level;
}
static void init();
// Update to log level to reflect runtime changes to manageable flags
static void update_level();
};
#endif // SHARE_VM_GC_G1_G1LOG_HPP

View file

@ -29,7 +29,6 @@
#include "classfile/vmSymbols.hpp" #include "classfile/vmSymbols.hpp"
#include "code/codeCache.hpp" #include "code/codeCache.hpp"
#include "code/icBuffer.hpp" #include "code/icBuffer.hpp"
#include "gc/g1/g1Log.hpp"
#include "gc/g1/g1MarkSweep.hpp" #include "gc/g1/g1MarkSweep.hpp"
#include "gc/g1/g1RootProcessor.hpp" #include "gc/g1/g1RootProcessor.hpp"
#include "gc/g1/g1StringDedup.hpp" #include "gc/g1/g1StringDedup.hpp"
@ -38,7 +37,7 @@
#include "gc/shared/gcLocker.hpp" #include "gc/shared/gcLocker.hpp"
#include "gc/shared/gcTimer.hpp" #include "gc/shared/gcTimer.hpp"
#include "gc/shared/gcTrace.hpp" #include "gc/shared/gcTrace.hpp"
#include "gc/shared/gcTraceTime.hpp" #include "gc/shared/gcTraceTime.inline.hpp"
#include "gc/shared/genCollectedHeap.hpp" #include "gc/shared/genCollectedHeap.hpp"
#include "gc/shared/modRefBarrierSet.hpp" #include "gc/shared/modRefBarrierSet.hpp"
#include "gc/shared/referencePolicy.hpp" #include "gc/shared/referencePolicy.hpp"
@ -123,7 +122,7 @@ void G1MarkSweep::allocate_stacks() {
void G1MarkSweep::mark_sweep_phase1(bool& marked_for_unloading, void G1MarkSweep::mark_sweep_phase1(bool& marked_for_unloading,
bool clear_all_softrefs) { bool clear_all_softrefs) {
// Recursively traverse all live objects and mark them // Recursively traverse all live objects and mark them
GCTraceTime tm("phase 1", G1Log::fine() && Verbose, true, gc_timer()); GCTraceTime(Trace, gc) tm("Phase 1: Mark live objects", gc_timer());
G1CollectedHeap* g1h = G1CollectedHeap::heap(); G1CollectedHeap* g1h = G1CollectedHeap::heap();
@ -183,13 +182,8 @@ void G1MarkSweep::mark_sweep_phase1(bool& marked_for_unloading,
// fail. At the end of the GC, the original mark word values // fail. At the end of the GC, the original mark word values
// (including hash values) are restored to the appropriate // (including hash values) are restored to the appropriate
// objects. // objects.
if (!VerifySilently) { GCTraceTime(Info, gc, verify)("During GC (full)");
gclog_or_tty->print(" VerifyDuringGC:(full)[Verifying "); g1h->verify(VerifyOption_G1UseMarkWord);
}
g1h->verify(VerifySilently, VerifyOption_G1UseMarkWord);
if (!VerifySilently) {
gclog_or_tty->print_cr("]");
}
} }
gc_tracer()->report_object_count_after_gc(&GenMarkSweep::is_alive); gc_tracer()->report_object_count_after_gc(&GenMarkSweep::is_alive);
@ -203,7 +197,7 @@ void G1MarkSweep::mark_sweep_phase2() {
// phase2, phase3 and phase4, but the ValidateMarkSweep live oops // phase2, phase3 and phase4, but the ValidateMarkSweep live oops
// tracking expects us to do so. See comment under phase4. // tracking expects us to do so. See comment under phase4.
GCTraceTime tm("phase 2", G1Log::fine() && Verbose, true, gc_timer()); GCTraceTime(Trace, gc) tm("Phase 2: Compute new object addresses", gc_timer());
prepare_compaction(); prepare_compaction();
} }
@ -236,7 +230,7 @@ void G1MarkSweep::mark_sweep_phase3() {
G1CollectedHeap* g1h = G1CollectedHeap::heap(); G1CollectedHeap* g1h = G1CollectedHeap::heap();
// Adjust the pointers to reflect the new locations // Adjust the pointers to reflect the new locations
GCTraceTime tm("phase 3", G1Log::fine() && Verbose, true, gc_timer()); GCTraceTime(Trace, gc) tm("Phase 3: Adjust pointers", gc_timer());
// Need cleared claim bits for the roots processing // Need cleared claim bits for the roots processing
ClassLoaderDataGraph::clear_claimed_marks(); ClassLoaderDataGraph::clear_claimed_marks();
@ -297,7 +291,7 @@ void G1MarkSweep::mark_sweep_phase4() {
// to use a higher index (saved from phase2) when verifying perm_gen. // to use a higher index (saved from phase2) when verifying perm_gen.
G1CollectedHeap* g1h = G1CollectedHeap::heap(); G1CollectedHeap* g1h = G1CollectedHeap::heap();
GCTraceTime tm("phase 4", G1Log::fine() && Verbose, true, gc_timer()); GCTraceTime(Trace, gc) tm("Phase 4: Move objects", gc_timer());
G1SpaceCompactClosure blk; G1SpaceCompactClosure blk;
g1h->heap_region_iterate(&blk); g1h->heap_region_iterate(&blk);

View file

@ -52,7 +52,7 @@ G1RemSet::G1RemSet(G1CollectedHeap* g1, CardTableModRefBS* ct_bs)
for (uint i = 0; i < n_workers(); i++) { for (uint i = 0; i < n_workers(); i++) {
_cset_rs_update_cl[i] = NULL; _cset_rs_update_cl[i] = NULL;
} }
if (G1SummarizeRSetStats) { if (log_is_enabled(Trace, gc, remset)) {
_prev_period_summary.initialize(this); _prev_period_summary.initialize(this);
} }
// Initialize the card queue set used to hold cards containing // Initialize the card queue set used to hold cards containing
@ -109,17 +109,6 @@ void ScanRSClosure::scanCard(size_t index, HeapRegion *r) {
} }
} }
void ScanRSClosure::printCard(HeapRegion* card_region, size_t card_index,
HeapWord* card_start) {
gclog_or_tty->print_cr("T %u Region [" PTR_FORMAT ", " PTR_FORMAT ") "
"RS names card " SIZE_FORMAT_HEX ": "
"[" PTR_FORMAT ", " PTR_FORMAT ")",
_worker_i,
p2i(card_region->bottom()), p2i(card_region->end()),
card_index,
p2i(card_start), p2i(card_start + G1BlockOffsetSharedArray::N_words));
}
void ScanRSClosure::scan_strong_code_roots(HeapRegion* r) { void ScanRSClosure::scan_strong_code_roots(HeapRegion* r) {
double scan_start = os::elapsedTime(); double scan_start = os::elapsedTime();
r->strong_code_roots_do(_code_root_cl); r->strong_code_roots_do(_code_root_cl);
@ -152,10 +141,6 @@ bool ScanRSClosure::doHeapRegion(HeapRegion* r) {
} }
if (current_card < jump_to_card) continue; if (current_card < jump_to_card) continue;
HeapWord* card_start = _g1h->bot_shared()->address_for_index(card_index); HeapWord* card_start = _g1h->bot_shared()->address_for_index(card_index);
#if 0
gclog_or_tty->print("Rem set iteration yielded card [" PTR_FORMAT ", " PTR_FORMAT ").\n",
card_start, card_start + CardTableModRefBS::card_size_in_words);
#endif
HeapRegion* card_region = _g1h->heap_region_containing(card_start); HeapRegion* card_region = _g1h->heap_region_containing(card_start);
_cards++; _cards++;
@ -526,31 +511,36 @@ bool G1RemSet::refine_card(jbyte* card_ptr, uint worker_i,
return has_refs_into_cset; return has_refs_into_cset;
} }
void G1RemSet::print_periodic_summary_info(const char* header) { void G1RemSet::print_periodic_summary_info(const char* header, uint period_count) {
G1RemSetSummary current; if ((G1SummarizeRSetStatsPeriod > 0) && log_is_enabled(Trace, gc, remset) &&
current.initialize(this); (period_count % G1SummarizeRSetStatsPeriod == 0)) {
_prev_period_summary.subtract_from(&current); if (!_prev_period_summary.initialized()) {
print_summary_info(&_prev_period_summary, header); _prev_period_summary.initialize(this);
}
_prev_period_summary.set(&current); G1RemSetSummary current;
current.initialize(this);
_prev_period_summary.subtract_from(&current);
LogHandle(gc, remset) log;
log.trace("%s", header);
ResourceMark rm;
_prev_period_summary.print_on(log.trace_stream());
_prev_period_summary.set(&current);
}
} }
void G1RemSet::print_summary_info() { void G1RemSet::print_summary_info() {
G1RemSetSummary current; LogHandle(gc, remset, exit) log;
current.initialize(this); if (log.is_trace()) {
log.trace(" Cumulative RS summary");
print_summary_info(&current, " Cumulative RS summary"); G1RemSetSummary current;
} current.initialize(this);
ResourceMark rm;
void G1RemSet::print_summary_info(G1RemSetSummary * summary, const char * header) { current.print_on(log.trace_stream());
assert(summary != NULL, "just checking");
if (header != NULL) {
gclog_or_tty->print_cr("%s", header);
} }
summary->print_on(gclog_or_tty);
} }
void G1RemSet::prepare_for_verify() { void G1RemSet::prepare_for_verify() {

View file

@ -33,6 +33,7 @@
class G1CollectedHeap; class G1CollectedHeap;
class ConcurrentG1Refine; class ConcurrentG1Refine;
class G1ParPushHeapRSClosure; class G1ParPushHeapRSClosure;
class outputStream;
// A G1RemSet in which each heap region has a rem set that records the // A G1RemSet in which each heap region has a rem set that records the
// external heap references into it. Uses a mod ref bs to track updates, // external heap references into it. Uses a mod ref bs to track updates,
@ -63,8 +64,6 @@ protected:
// references into the collection set. // references into the collection set.
G1ParPushHeapRSClosure** _cset_rs_update_cl; G1ParPushHeapRSClosure** _cset_rs_update_cl;
// Print the given summary info
virtual void print_summary_info(G1RemSetSummary * summary, const char * header = NULL);
public: public:
// This is called to reset dual hash tables after the gc pause // This is called to reset dual hash tables after the gc pause
// is finished and the initial hash table is no longer being // is finished and the initial hash table is no longer being
@ -135,7 +134,7 @@ public:
virtual void print_summary_info(); virtual void print_summary_info();
// Print accumulated summary info from the last time called. // Print accumulated summary info from the last time called.
virtual void print_periodic_summary_info(const char* header); virtual void print_periodic_summary_info(const char* header, uint period_count);
// Prepare remembered set for verification. // Prepare remembered set for verification.
virtual void prepare_for_verify(); virtual void prepare_for_verify();

View file

@ -271,7 +271,7 @@ public:
void print_summary_on(outputStream* out) { void print_summary_on(outputStream* out) {
RegionTypeCounter* counters[] = { &_young, &_humonguous, &_free, &_old, NULL }; RegionTypeCounter* counters[] = { &_young, &_humonguous, &_free, &_old, NULL };
out->print_cr("\n Current rem set statistics"); out->print_cr(" Current rem set statistics");
out->print_cr(" Total per region rem sets sizes = " SIZE_FORMAT "K." out->print_cr(" Total per region rem sets sizes = " SIZE_FORMAT "K."
" Max = " SIZE_FORMAT "K.", " Max = " SIZE_FORMAT "K.",
round_to_K(total_rs_mem_sz()), round_to_K(max_rs_mem_sz())); round_to_K(total_rs_mem_sz()), round_to_K(max_rs_mem_sz()));
@ -323,7 +323,7 @@ public:
}; };
void G1RemSetSummary::print_on(outputStream* out) { void G1RemSetSummary::print_on(outputStream* out) {
out->print_cr("\n Recent concurrent refinement statistics"); out->print_cr(" Recent concurrent refinement statistics");
out->print_cr(" Processed " SIZE_FORMAT " cards", out->print_cr(" Processed " SIZE_FORMAT " cards",
num_concurrent_refined_cards()); num_concurrent_refined_cards());
out->print_cr(" Of " SIZE_FORMAT " completed buffers:", num_processed_buf_total()); out->print_cr(" Of " SIZE_FORMAT " completed buffers:", num_processed_buf_total());

View file

@ -85,6 +85,7 @@ public:
// initialize and get the first sampling // initialize and get the first sampling
void initialize(G1RemSet* remset); void initialize(G1RemSet* remset);
bool const initialized() { return _rs_threads_vtimes != NULL; }
void print_on(outputStream* out); void print_on(outputStream* out);

View file

@ -28,6 +28,7 @@
#include "gc/g1/heapRegion.hpp" #include "gc/g1/heapRegion.hpp"
#include "gc/g1/satbMarkQueue.hpp" #include "gc/g1/satbMarkQueue.hpp"
#include "gc/shared/memset_with_concurrent_readers.hpp" #include "gc/shared/memset_with_concurrent_readers.hpp"
#include "logging/log.hpp"
#include "oops/oop.inline.hpp" #include "oops/oop.inline.hpp"
#include "runtime/atomic.inline.hpp" #include "runtime/atomic.inline.hpp"
#include "runtime/mutexLocker.hpp" #include "runtime/mutexLocker.hpp"
@ -147,17 +148,10 @@ void G1SATBCardTableLoggingModRefBS::initialize(G1RegionToSpaceMapper* mapper) {
assert(byte_for(low_bound) == &_byte_map[0], "Checking start of map"); assert(byte_for(low_bound) == &_byte_map[0], "Checking start of map");
assert(byte_for(high_bound-1) <= &_byte_map[_last_valid_index], "Checking end of map"); assert(byte_for(high_bound-1) <= &_byte_map[_last_valid_index], "Checking end of map");
if (TraceCardTableModRefBS) { log_trace(gc, barrier)("G1SATBCardTableModRefBS::G1SATBCardTableModRefBS: ");
gclog_or_tty->print_cr("G1SATBCardTableModRefBS::G1SATBCardTableModRefBS: "); log_trace(gc, barrier)(" &_byte_map[0]: " INTPTR_FORMAT " &_byte_map[_last_valid_index]: " INTPTR_FORMAT,
gclog_or_tty->print_cr(" " p2i(&_byte_map[0]), p2i(&_byte_map[_last_valid_index]));
" &_byte_map[0]: " INTPTR_FORMAT log_trace(gc, barrier)(" byte_map_base: " INTPTR_FORMAT, p2i(byte_map_base));
" &_byte_map[_last_valid_index]: " INTPTR_FORMAT,
p2i(&_byte_map[0]),
p2i(&_byte_map[_last_valid_index]));
gclog_or_tty->print_cr(" "
" byte_map_base: " INTPTR_FORMAT,
p2i(byte_map_base));
}
} }
void void

View file

@ -28,6 +28,7 @@
#include "gc/g1/g1StringDedup.hpp" #include "gc/g1/g1StringDedup.hpp"
#include "gc/g1/g1StringDedupQueue.hpp" #include "gc/g1/g1StringDedupQueue.hpp"
#include "gc/shared/gcLocker.hpp" #include "gc/shared/gcLocker.hpp"
#include "logging/log.hpp"
#include "oops/oop.inline.hpp" #include "oops/oop.inline.hpp"
#include "runtime/atomic.inline.hpp" #include "runtime/atomic.inline.hpp"
#include "runtime/mutexLocker.hpp" #include "runtime/mutexLocker.hpp"
@ -152,10 +153,9 @@ void G1StringDedupQueue::unlink_or_oops_do(G1StringDedupUnlinkOrOopsDoClosure* c
} }
} }
void G1StringDedupQueue::print_statistics(outputStream* st) { void G1StringDedupQueue::print_statistics() {
st->print_cr( log_debug(gc, stringdedup)(" [Queue]");
" [Queue]\n" log_debug(gc, stringdedup)(" [Dropped: " UINTX_FORMAT "]", _queue->_dropped);
" [Dropped: " UINTX_FORMAT "]", _queue->_dropped);
} }
void G1StringDedupQueue::verify() { void G1StringDedupQueue::verify() {

View file

@ -94,7 +94,7 @@ public:
static void unlink_or_oops_do(G1StringDedupUnlinkOrOopsDoClosure* cl); static void unlink_or_oops_do(G1StringDedupUnlinkOrOopsDoClosure* cl);
static void print_statistics(outputStream* st); static void print_statistics();
static void verify(); static void verify();
}; };

View file

@ -24,6 +24,7 @@
#include "precompiled.hpp" #include "precompiled.hpp"
#include "gc/g1/g1StringDedupStat.hpp" #include "gc/g1/g1StringDedupStat.hpp"
#include "logging/log.hpp"
G1StringDedupStat::G1StringDedupStat() : G1StringDedupStat::G1StringDedupStat() :
_inspected(0), _inspected(0),
@ -68,7 +69,7 @@ void G1StringDedupStat::add(const G1StringDedupStat& stat) {
_block_elapsed += stat._block_elapsed; _block_elapsed += stat._block_elapsed;
} }
void G1StringDedupStat::print_summary(outputStream* st, const G1StringDedupStat& last_stat, const G1StringDedupStat& total_stat) { void G1StringDedupStat::print_summary(const G1StringDedupStat& last_stat, const G1StringDedupStat& total_stat) {
double total_deduped_bytes_percent = 0.0; double total_deduped_bytes_percent = 0.0;
if (total_stat._new_bytes > 0) { if (total_stat._new_bytes > 0) {
@ -76,10 +77,8 @@ void G1StringDedupStat::print_summary(outputStream* st, const G1StringDedupStat&
total_deduped_bytes_percent = (double)total_stat._deduped_bytes / (double)total_stat._new_bytes * 100.0; total_deduped_bytes_percent = (double)total_stat._deduped_bytes / (double)total_stat._new_bytes * 100.0;
} }
st->date_stamp(PrintGCDateStamps); log_info(gc, stringdedup)(
st->stamp(PrintGCTimeStamps); "Concurrent String Deduplication "
st->print_cr(
"[GC concurrent-string-deduplication, "
G1_STRDEDUP_BYTES_FORMAT_NS "->" G1_STRDEDUP_BYTES_FORMAT_NS "(" G1_STRDEDUP_BYTES_FORMAT_NS "), avg " G1_STRDEDUP_BYTES_FORMAT_NS "->" G1_STRDEDUP_BYTES_FORMAT_NS "(" G1_STRDEDUP_BYTES_FORMAT_NS "), avg "
G1_STRDEDUP_PERCENT_FORMAT_NS ", " G1_STRDEDUP_TIME_FORMAT "]", G1_STRDEDUP_PERCENT_FORMAT_NS ", " G1_STRDEDUP_TIME_FORMAT "]",
G1_STRDEDUP_BYTES_PARAM(last_stat._new_bytes), G1_STRDEDUP_BYTES_PARAM(last_stat._new_bytes),
@ -89,7 +88,7 @@ void G1StringDedupStat::print_summary(outputStream* st, const G1StringDedupStat&
last_stat._exec_elapsed); last_stat._exec_elapsed);
} }
void G1StringDedupStat::print_statistics(outputStream* st, const G1StringDedupStat& stat, bool total) { void G1StringDedupStat::print_statistics(const G1StringDedupStat& stat, bool total) {
double young_percent = 0.0; double young_percent = 0.0;
double old_percent = 0.0; double old_percent = 0.0;
double skipped_percent = 0.0; double skipped_percent = 0.0;
@ -134,29 +133,24 @@ void G1StringDedupStat::print_statistics(outputStream* st, const G1StringDedupSt
} }
if (total) { if (total) {
st->print_cr( log_debug(gc, stringdedup)(
" [Total Exec: " UINTX_FORMAT "/" G1_STRDEDUP_TIME_FORMAT ", Idle: " UINTX_FORMAT "/" G1_STRDEDUP_TIME_FORMAT ", Blocked: " UINTX_FORMAT "/" G1_STRDEDUP_TIME_FORMAT "]", " [Total Exec: " UINTX_FORMAT "/" G1_STRDEDUP_TIME_FORMAT ", Idle: " UINTX_FORMAT "/" G1_STRDEDUP_TIME_FORMAT ", Blocked: " UINTX_FORMAT "/" G1_STRDEDUP_TIME_FORMAT "]",
stat._exec, stat._exec_elapsed, stat._idle, stat._idle_elapsed, stat._block, stat._block_elapsed); stat._exec, stat._exec_elapsed, stat._idle, stat._idle_elapsed, stat._block, stat._block_elapsed);
} else { } else {
st->print_cr( log_debug(gc, stringdedup)(
" [Last Exec: " G1_STRDEDUP_TIME_FORMAT ", Idle: " G1_STRDEDUP_TIME_FORMAT ", Blocked: " UINTX_FORMAT "/" G1_STRDEDUP_TIME_FORMAT "]", " [Last Exec: " G1_STRDEDUP_TIME_FORMAT ", Idle: " G1_STRDEDUP_TIME_FORMAT ", Blocked: " UINTX_FORMAT "/" G1_STRDEDUP_TIME_FORMAT "]",
stat._exec_elapsed, stat._idle_elapsed, stat._block, stat._block_elapsed); stat._exec_elapsed, stat._idle_elapsed, stat._block, stat._block_elapsed);
} }
st->print_cr( log_debug(gc, stringdedup)(" [Inspected: " G1_STRDEDUP_OBJECTS_FORMAT "]", stat._inspected);
" [Inspected: " G1_STRDEDUP_OBJECTS_FORMAT "]\n" log_debug(gc, stringdedup)(" [Skipped: " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ")]", stat._skipped, skipped_percent);
" [Skipped: " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ")]\n" log_debug(gc, stringdedup)(" [Hashed: " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ")]", stat._hashed, hashed_percent);
" [Hashed: " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ")]\n" log_debug(gc, stringdedup)(" [Known: " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ")]", stat._known, known_percent);
" [Known: " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ")]\n" log_debug(gc, stringdedup)(" [New: " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ") " G1_STRDEDUP_BYTES_FORMAT "]",
" [New: " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ") " G1_STRDEDUP_BYTES_FORMAT "]\n" stat._new, new_percent, G1_STRDEDUP_BYTES_PARAM(stat._new_bytes));
" [Deduplicated: " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ") " G1_STRDEDUP_BYTES_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ")]\n" log_debug(gc, stringdedup)(" [Deduplicated: " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ") " G1_STRDEDUP_BYTES_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ")]",
" [Young: " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ") " G1_STRDEDUP_BYTES_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ")]\n" stat._deduped, deduped_percent, G1_STRDEDUP_BYTES_PARAM(stat._deduped_bytes), deduped_bytes_percent);
" [Old: " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ") " G1_STRDEDUP_BYTES_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ")]", log_debug(gc, stringdedup)(" [Young: " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ") " G1_STRDEDUP_BYTES_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ")]",
stat._inspected, stat._deduped_young, deduped_young_percent, G1_STRDEDUP_BYTES_PARAM(stat._deduped_young_bytes), deduped_young_bytes_percent);
stat._skipped, skipped_percent, log_debug(gc, stringdedup)(" [Old: " G1_STRDEDUP_OBJECTS_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ") " G1_STRDEDUP_BYTES_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT ")]",
stat._hashed, hashed_percent, stat._deduped_old, deduped_old_percent, G1_STRDEDUP_BYTES_PARAM(stat._deduped_old_bytes), deduped_old_bytes_percent);
stat._known, known_percent,
stat._new, new_percent, G1_STRDEDUP_BYTES_PARAM(stat._new_bytes),
stat._deduped, deduped_percent, G1_STRDEDUP_BYTES_PARAM(stat._deduped_bytes), deduped_bytes_percent,
stat._deduped_young, deduped_young_percent, G1_STRDEDUP_BYTES_PARAM(stat._deduped_young_bytes), deduped_young_bytes_percent,
stat._deduped_old, deduped_old_percent, G1_STRDEDUP_BYTES_PARAM(stat._deduped_old_bytes), deduped_old_bytes_percent);
} }

View file

@ -135,8 +135,8 @@ public:
void add(const G1StringDedupStat& stat); void add(const G1StringDedupStat& stat);
static void print_summary(outputStream* st, const G1StringDedupStat& last_stat, const G1StringDedupStat& total_stat); static void print_summary(const G1StringDedupStat& last_stat, const G1StringDedupStat& total_stat);
static void print_statistics(outputStream* st, const G1StringDedupStat& stat, bool total); static void print_statistics(const G1StringDedupStat& stat, bool total);
}; };
#endif // SHARE_VM_GC_G1_G1STRINGDEDUPSTAT_HPP #endif // SHARE_VM_GC_G1_G1STRINGDEDUPSTAT_HPP

View file

@ -30,6 +30,7 @@
#include "gc/g1/g1StringDedup.hpp" #include "gc/g1/g1StringDedup.hpp"
#include "gc/g1/g1StringDedupTable.hpp" #include "gc/g1/g1StringDedupTable.hpp"
#include "gc/shared/gcLocker.hpp" #include "gc/shared/gcLocker.hpp"
#include "logging/log.hpp"
#include "memory/padded.inline.hpp" #include "memory/padded.inline.hpp"
#include "oops/oop.inline.hpp" #include "oops/oop.inline.hpp"
#include "oops/typeArrayOop.hpp" #include "oops/typeArrayOop.hpp"
@ -568,19 +569,16 @@ void G1StringDedupTable::trim_entry_cache() {
_entry_cache->trim(max_cache_size); _entry_cache->trim(max_cache_size);
} }
void G1StringDedupTable::print_statistics(outputStream* st) { void G1StringDedupTable::print_statistics() {
st->print_cr( LogHandle(gc, stringdedup) log;
" [Table]\n" log.debug(" [Table]");
" [Memory Usage: " G1_STRDEDUP_BYTES_FORMAT_NS "]\n" log.debug(" [Memory Usage: " G1_STRDEDUP_BYTES_FORMAT_NS "]",
" [Size: " SIZE_FORMAT ", Min: " SIZE_FORMAT ", Max: " SIZE_FORMAT "]\n" G1_STRDEDUP_BYTES_PARAM(_table->_size * sizeof(G1StringDedupEntry*) + (_table->_entries + _entry_cache->size()) * sizeof(G1StringDedupEntry)));
" [Entries: " UINTX_FORMAT ", Load: " G1_STRDEDUP_PERCENT_FORMAT_NS ", Cached: " UINTX_FORMAT ", Added: " UINTX_FORMAT ", Removed: " UINTX_FORMAT "]\n" log.debug(" [Size: " SIZE_FORMAT ", Min: " SIZE_FORMAT ", Max: " SIZE_FORMAT "]", _table->_size, _min_size, _max_size);
" [Resize Count: " UINTX_FORMAT ", Shrink Threshold: " UINTX_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT_NS "), Grow Threshold: " UINTX_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT_NS ")]\n" log.debug(" [Entries: " UINTX_FORMAT ", Load: " G1_STRDEDUP_PERCENT_FORMAT_NS ", Cached: " UINTX_FORMAT ", Added: " UINTX_FORMAT ", Removed: " UINTX_FORMAT "]",
" [Rehash Count: " UINTX_FORMAT ", Rehash Threshold: " UINTX_FORMAT ", Hash Seed: 0x%x]\n" _table->_entries, (double)_table->_entries / (double)_table->_size * 100.0, _entry_cache->size(), _entries_added, _entries_removed);
" [Age Threshold: " UINTX_FORMAT "]", log.debug(" [Resize Count: " UINTX_FORMAT ", Shrink Threshold: " UINTX_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT_NS "), Grow Threshold: " UINTX_FORMAT "(" G1_STRDEDUP_PERCENT_FORMAT_NS ")]",
G1_STRDEDUP_BYTES_PARAM(_table->_size * sizeof(G1StringDedupEntry*) + (_table->_entries + _entry_cache->size()) * sizeof(G1StringDedupEntry)), _resize_count, _table->_shrink_threshold, _shrink_load_factor * 100.0, _table->_grow_threshold, _grow_load_factor * 100.0);
_table->_size, _min_size, _max_size, log.debug(" [Rehash Count: " UINTX_FORMAT ", Rehash Threshold: " UINTX_FORMAT ", Hash Seed: 0x%x]", _rehash_count, _rehash_threshold, _table->_hash_seed);
_table->_entries, (double)_table->_entries / (double)_table->_size * 100.0, _entry_cache->size(), _entries_added, _entries_removed, log.debug(" [Age Threshold: " UINTX_FORMAT "]", StringDeduplicationAgeThreshold);
_resize_count, _table->_shrink_threshold, _shrink_load_factor * 100.0, _table->_grow_threshold, _grow_load_factor * 100.0,
_rehash_count, _rehash_threshold, _table->_hash_seed,
StringDeduplicationAgeThreshold);
} }

View file

@ -234,7 +234,7 @@ public:
static void unlink_or_oops_do(G1StringDedupUnlinkOrOopsDoClosure* cl, uint worker_id); static void unlink_or_oops_do(G1StringDedupUnlinkOrOopsDoClosure* cl, uint worker_id);
static void print_statistics(outputStream* st); static void print_statistics();
static void verify(); static void verify();
}; };

View file

@ -24,12 +24,12 @@
#include "precompiled.hpp" #include "precompiled.hpp"
#include "classfile/stringTable.hpp" #include "classfile/stringTable.hpp"
#include "gc/g1/g1Log.hpp"
#include "gc/g1/g1StringDedup.hpp" #include "gc/g1/g1StringDedup.hpp"
#include "gc/g1/g1StringDedupQueue.hpp" #include "gc/g1/g1StringDedupQueue.hpp"
#include "gc/g1/g1StringDedupTable.hpp" #include "gc/g1/g1StringDedupTable.hpp"
#include "gc/g1/g1StringDedupThread.hpp" #include "gc/g1/g1StringDedupThread.hpp"
#include "gc/g1/suspendibleThreadSet.hpp" #include "gc/g1/suspendibleThreadSet.hpp"
#include "logging/log.hpp"
#include "oops/oop.inline.hpp" #include "oops/oop.inline.hpp"
#include "runtime/atomic.inline.hpp" #include "runtime/atomic.inline.hpp"
@ -129,7 +129,7 @@ void G1StringDedupThread::run() {
// Print statistics // Print statistics
total_stat.add(stat); total_stat.add(stat);
print(gclog_or_tty, stat, total_stat); print(stat, total_stat);
} }
} }
@ -152,14 +152,14 @@ void G1StringDedupThread::stop() {
} }
} }
void G1StringDedupThread::print(outputStream* st, const G1StringDedupStat& last_stat, const G1StringDedupStat& total_stat) { void G1StringDedupThread::print(const G1StringDedupStat& last_stat, const G1StringDedupStat& total_stat) {
if (G1Log::fine() || PrintStringDeduplicationStatistics) { if (log_is_enabled(Info, gc, stringdedup)) {
G1StringDedupStat::print_summary(st, last_stat, total_stat); G1StringDedupStat::print_summary(last_stat, total_stat);
if (PrintStringDeduplicationStatistics) { if (log_is_enabled(Debug, gc, stringdedup)) {
G1StringDedupStat::print_statistics(st, last_stat, false); G1StringDedupStat::print_statistics(last_stat, false);
G1StringDedupStat::print_statistics(st, total_stat, true); G1StringDedupStat::print_statistics(total_stat, true);
G1StringDedupTable::print_statistics(st); G1StringDedupTable::print_statistics();
G1StringDedupQueue::print_statistics(st); G1StringDedupQueue::print_statistics();
} }
} }
} }

View file

@ -43,7 +43,7 @@ private:
G1StringDedupThread(); G1StringDedupThread();
~G1StringDedupThread(); ~G1StringDedupThread();
void print(outputStream* st, const G1StringDedupStat& last_stat, const G1StringDedupStat& total_stat); void print(const G1StringDedupStat& last_stat, const G1StringDedupStat& total_stat);
public: public:
static void create(); static void create();

View file

@ -53,32 +53,14 @@
"Overhead of concurrent marking") \ "Overhead of concurrent marking") \
range(0, 100) \ range(0, 100) \
\ \
develop(intx, G1MarkingVerboseLevel, 0, \
"Level (0-4) of verboseness of the marking code") \
range(0, 4) \
\
develop(bool, G1TraceMarkStackOverflow, false, \
"If true, extra debugging code for CM restart for ovflw.") \
\
diagnostic(bool, G1SummarizeConcMark, false, \
"Summarize concurrent mark info") \
\
diagnostic(bool, G1SummarizeRSetStats, false, \
"Summarize remembered set processing info") \
\
diagnostic(intx, G1SummarizeRSetStatsPeriod, 0, \ diagnostic(intx, G1SummarizeRSetStatsPeriod, 0, \
"The period (in number of GCs) at which we will generate " \ "The period (in number of GCs) at which we will generate " \
"update buffer processing info " \ "update buffer processing info " \
"(0 means do not periodically generate this info); " \ "(0 means do not periodically generate this info); " \
"it also requires -XX:+G1SummarizeRSetStats") \ "it also requires that logging is enabled on the trace" \
"level for gc+remset") \
range(0, max_intx) \ range(0, max_intx) \
\ \
diagnostic(bool, G1TraceConcRefinement, false, \
"Trace G1 concurrent refinement") \
\
experimental(bool, G1TraceStringSymbolTableScrubbing, false, \
"Trace information string and symbol table scrubbing.") \
\
product(double, G1ConcMarkStepDurationMillis, 10.0, \ product(double, G1ConcMarkStepDurationMillis, 10.0, \
"Target duration of individual concurrent marking steps " \ "Target duration of individual concurrent marking steps " \
"in milliseconds.") \ "in milliseconds.") \
@ -121,10 +103,6 @@
develop(bool, G1RSBarrierRegionFilter, true, \ develop(bool, G1RSBarrierRegionFilter, true, \
"If true, generate region filtering code in RS barrier") \ "If true, generate region filtering code in RS barrier") \
\ \
diagnostic(bool, G1PrintRegionLivenessInfo, false, \
"Prints the liveness information for all regions in the heap " \
"at the end of a marking cycle.") \
\
product(size_t, G1UpdateBufferSize, 256, \ product(size_t, G1UpdateBufferSize, 256, \
"Size of an update buffer") \ "Size of an update buffer") \
range(1, NOT_LP64(32*M) LP64_ONLY(1*G)) \ range(1, NOT_LP64(32*M) LP64_ONLY(1*G)) \
@ -205,12 +183,6 @@
develop(bool, G1ScrubRemSets, true, \ develop(bool, G1ScrubRemSets, true, \
"When true, do RS scrubbing after cleanup.") \ "When true, do RS scrubbing after cleanup.") \
\ \
develop(bool, G1RSScrubVerbose, false, \
"When true, do RS scrubbing with verbose output.") \
\
develop(bool, G1YoungSurvRateVerbose, false, \
"print out the survival rate of young regions according to age.") \
\
develop(intx, G1YoungSurvRateNumRegionsSummary, 0, \ develop(intx, G1YoungSurvRateNumRegionsSummary, 0, \
"the number of regions for which we'll print a surv rate " \ "the number of regions for which we'll print a surv rate " \
"summary.") \ "summary.") \
@ -222,10 +194,6 @@
"to minimize the probability of promotion failure.") \ "to minimize the probability of promotion failure.") \
range(0, 50) \ range(0, 50) \
\ \
diagnostic(bool, G1PrintHeapRegions, false, \
"If set G1 will print information on which regions are being " \
"allocated and which are reclaimed.") \
\
develop(bool, G1HRRSUseSparseTable, true, \ develop(bool, G1HRRSUseSparseTable, true, \
"When true, use sparse table to save space.") \ "When true, use sparse table to save space.") \
\ \
@ -254,9 +222,6 @@
"The number of regions we will add to the secondary free list " \ "The number of regions we will add to the secondary free list " \
"at every append operation") \ "at every append operation") \
\ \
develop(bool, G1ConcRegionFreeingVerbose, false, \
"Enables verboseness during concurrent region freeing") \
\
develop(bool, G1StressConcRegionFreeing, false, \ develop(bool, G1StressConcRegionFreeing, false, \
"It stresses the concurrent region freeing operation") \ "It stresses the concurrent region freeing operation") \
\ \
@ -310,18 +275,11 @@
"Try to reclaim dead large objects that have a few stale " \ "Try to reclaim dead large objects that have a few stale " \
"references at every young GC.") \ "references at every young GC.") \
\ \
experimental(bool, G1TraceEagerReclaimHumongousObjects, false, \
"Print some information about large object liveness " \
"at every young GC.") \
\
experimental(uintx, G1OldCSetRegionThresholdPercent, 10, \ experimental(uintx, G1OldCSetRegionThresholdPercent, 10, \
"An upper bound for the number of old CSet regions expressed " \ "An upper bound for the number of old CSet regions expressed " \
"as a percentage of the heap size.") \ "as a percentage of the heap size.") \
range(0, 100) \ range(0, 100) \
\ \
experimental(ccstr, G1LogLevel, NULL, \
"Log level for G1 logging: fine, finer, finest") \
\
notproduct(bool, G1EvacuationFailureALot, false, \ notproduct(bool, G1EvacuationFailureALot, false, \
"Force use of evacuation failure handling during certain " \ "Force use of evacuation failure handling during certain " \
"evacuation pauses") \ "evacuation pauses") \

View file

@ -34,6 +34,7 @@
#include "gc/shared/genOopClosures.inline.hpp" #include "gc/shared/genOopClosures.inline.hpp"
#include "gc/shared/liveRange.hpp" #include "gc/shared/liveRange.hpp"
#include "gc/shared/space.inline.hpp" #include "gc/shared/space.inline.hpp"
#include "logging/log.hpp"
#include "memory/iterator.hpp" #include "memory/iterator.hpp"
#include "oops/oop.inline.hpp" #include "oops/oop.inline.hpp"
#include "runtime/atomic.inline.hpp" #include "runtime/atomic.inline.hpp"
@ -479,10 +480,8 @@ class VerifyStrongCodeRootOopClosure: public OopClosure {
// Object is in the region. Check that its less than top // Object is in the region. Check that its less than top
if (_hr->top() <= (HeapWord*)obj) { if (_hr->top() <= (HeapWord*)obj) {
// Object is above top // Object is above top
gclog_or_tty->print_cr("Object " PTR_FORMAT " in region " log_info(gc, verify)("Object " PTR_FORMAT " in region [" PTR_FORMAT ", " PTR_FORMAT ") is above top " PTR_FORMAT,
"[" PTR_FORMAT ", " PTR_FORMAT ") is above " p2i(obj), p2i(_hr->bottom()), p2i(_hr->end()), p2i(_hr->top()));
"top " PTR_FORMAT,
p2i(obj), p2i(_hr->bottom()), p2i(_hr->end()), p2i(_hr->top()));
_failures = true; _failures = true;
return; return;
} }
@ -515,23 +514,19 @@ public:
if (nm != NULL) { if (nm != NULL) {
// Verify that the nemthod is live // Verify that the nemthod is live
if (!nm->is_alive()) { if (!nm->is_alive()) {
gclog_or_tty->print_cr("region [" PTR_FORMAT "," PTR_FORMAT "] has dead nmethod " log_info(gc, verify)("region [" PTR_FORMAT "," PTR_FORMAT "] has dead nmethod " PTR_FORMAT " in its strong code roots",
PTR_FORMAT " in its strong code roots", p2i(_hr->bottom()), p2i(_hr->end()), p2i(nm));
p2i(_hr->bottom()), p2i(_hr->end()), p2i(nm));
_failures = true; _failures = true;
} else { } else {
VerifyStrongCodeRootOopClosure oop_cl(_hr, nm); VerifyStrongCodeRootOopClosure oop_cl(_hr, nm);
nm->oops_do(&oop_cl); nm->oops_do(&oop_cl);
if (!oop_cl.has_oops_in_region()) { if (!oop_cl.has_oops_in_region()) {
gclog_or_tty->print_cr("region [" PTR_FORMAT "," PTR_FORMAT "] has nmethod " log_info(gc, verify)("region [" PTR_FORMAT "," PTR_FORMAT "] has nmethod " PTR_FORMAT " in its strong code roots with no pointers into region",
PTR_FORMAT " in its strong code roots " p2i(_hr->bottom()), p2i(_hr->end()), p2i(nm));
"with no pointers into region",
p2i(_hr->bottom()), p2i(_hr->end()), p2i(nm));
_failures = true; _failures = true;
} else if (oop_cl.failures()) { } else if (oop_cl.failures()) {
gclog_or_tty->print_cr("region [" PTR_FORMAT "," PTR_FORMAT "] has other " log_info(gc, verify)("region [" PTR_FORMAT "," PTR_FORMAT "] has other failures for nmethod " PTR_FORMAT,
"failures for nmethod " PTR_FORMAT, p2i(_hr->bottom()), p2i(_hr->end()), p2i(nm));
p2i(_hr->bottom()), p2i(_hr->end()), p2i(nm));
_failures = true; _failures = true;
} }
} }
@ -564,9 +559,8 @@ void HeapRegion::verify_strong_code_roots(VerifyOption vo, bool* failures) const
// on its strong code root list // on its strong code root list
if (is_empty()) { if (is_empty()) {
if (strong_code_roots_length > 0) { if (strong_code_roots_length > 0) {
gclog_or_tty->print_cr("region [" PTR_FORMAT "," PTR_FORMAT "] is empty " log_info(gc, verify)("region [" PTR_FORMAT "," PTR_FORMAT "] is empty but has " SIZE_FORMAT " code root entries",
"but has " SIZE_FORMAT " code root entries", p2i(bottom()), p2i(end()), strong_code_roots_length);
p2i(bottom()), p2i(end()), strong_code_roots_length);
*failures = true; *failures = true;
} }
return; return;
@ -574,9 +568,8 @@ void HeapRegion::verify_strong_code_roots(VerifyOption vo, bool* failures) const
if (is_continues_humongous()) { if (is_continues_humongous()) {
if (strong_code_roots_length > 0) { if (strong_code_roots_length > 0) {
gclog_or_tty->print_cr("region " HR_FORMAT " is a continuation of a humongous " log_info(gc, verify)("region " HR_FORMAT " is a continuation of a humongous region but has " SIZE_FORMAT " code root entries",
"region but has " SIZE_FORMAT " code root entries", HR_FORMAT_PARAMS(this), strong_code_roots_length);
HR_FORMAT_PARAMS(this), strong_code_roots_length);
*failures = true; *failures = true;
} }
return; return;
@ -590,7 +583,7 @@ void HeapRegion::verify_strong_code_roots(VerifyOption vo, bool* failures) const
} }
} }
void HeapRegion::print() const { print_on(gclog_or_tty); } void HeapRegion::print() const { print_on(tty); }
void HeapRegion::print_on(outputStream* st) const { void HeapRegion::print_on(outputStream* st) const {
st->print("|%4u", this->_hrm_index); st->print("|%4u", this->_hrm_index);
st->print("|" PTR_FORMAT ", " PTR_FORMAT ", " PTR_FORMAT, st->print("|" PTR_FORMAT ", " PTR_FORMAT ", " PTR_FORMAT,
@ -651,6 +644,7 @@ public:
assert(!_g1h->is_obj_dead_cond(_containing_obj, _vo), assert(!_g1h->is_obj_dead_cond(_containing_obj, _vo),
"Precondition"); "Precondition");
T heap_oop = oopDesc::load_heap_oop(p); T heap_oop = oopDesc::load_heap_oop(p);
LogHandle(gc, verify) log;
if (!oopDesc::is_null(heap_oop)) { if (!oopDesc::is_null(heap_oop)) {
oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
bool failed = false; bool failed = false;
@ -659,35 +653,26 @@ public:
Mutex::_no_safepoint_check_flag); Mutex::_no_safepoint_check_flag);
if (!_failures) { if (!_failures) {
gclog_or_tty->cr(); log.info("----------");
gclog_or_tty->print_cr("----------");
} }
ResourceMark rm;
if (!_g1h->is_in_closed_subset(obj)) { if (!_g1h->is_in_closed_subset(obj)) {
HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p); HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
gclog_or_tty->print_cr("Field " PTR_FORMAT log.info("Field " PTR_FORMAT " of live obj " PTR_FORMAT " in region [" PTR_FORMAT ", " PTR_FORMAT ")",
" of live obj " PTR_FORMAT " in region " p2i(p), p2i(_containing_obj), p2i(from->bottom()), p2i(from->end()));
"[" PTR_FORMAT ", " PTR_FORMAT ")", print_object(log.info_stream(), _containing_obj);
p2i(p), p2i(_containing_obj), log.info("points to obj " PTR_FORMAT " not in the heap", p2i(obj));
p2i(from->bottom()), p2i(from->end()));
print_object(gclog_or_tty, _containing_obj);
gclog_or_tty->print_cr("points to obj " PTR_FORMAT " not in the heap",
p2i(obj));
} else { } else {
HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p); HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
HeapRegion* to = _g1h->heap_region_containing((HeapWord*)obj); HeapRegion* to = _g1h->heap_region_containing((HeapWord*)obj);
gclog_or_tty->print_cr("Field " PTR_FORMAT log.info("Field " PTR_FORMAT " of live obj " PTR_FORMAT " in region [" PTR_FORMAT ", " PTR_FORMAT ")",
" of live obj " PTR_FORMAT " in region " p2i(p), p2i(_containing_obj), p2i(from->bottom()), p2i(from->end()));
"[" PTR_FORMAT ", " PTR_FORMAT ")", print_object(log.info_stream(), _containing_obj);
p2i(p), p2i(_containing_obj), log.info("points to dead obj " PTR_FORMAT " in region [" PTR_FORMAT ", " PTR_FORMAT ")",
p2i(from->bottom()), p2i(from->end())); p2i(obj), p2i(to->bottom()), p2i(to->end()));
print_object(gclog_or_tty, _containing_obj); print_object(log.info_stream(), obj);
gclog_or_tty->print_cr("points to dead obj " PTR_FORMAT " in region "
"[" PTR_FORMAT ", " PTR_FORMAT ")",
p2i(obj), p2i(to->bottom()), p2i(to->end()));
print_object(gclog_or_tty, obj);
} }
gclog_or_tty->print_cr("----------"); log.info("----------");
gclog_or_tty->flush();
_failures = true; _failures = true;
failed = true; failed = true;
_n_failures++; _n_failures++;
@ -714,25 +699,17 @@ public:
Mutex::_no_safepoint_check_flag); Mutex::_no_safepoint_check_flag);
if (!_failures) { if (!_failures) {
gclog_or_tty->cr(); log.info("----------");
gclog_or_tty->print_cr("----------");
} }
gclog_or_tty->print_cr("Missing rem set entry:"); log.info("Missing rem set entry:");
gclog_or_tty->print_cr("Field " PTR_FORMAT " " log.info("Field " PTR_FORMAT " of obj " PTR_FORMAT ", in region " HR_FORMAT,
"of obj " PTR_FORMAT ", " p2i(p), p2i(_containing_obj), HR_FORMAT_PARAMS(from));
"in region " HR_FORMAT, ResourceMark rm;
p2i(p), p2i(_containing_obj), _containing_obj->print_on(log.info_stream());
HR_FORMAT_PARAMS(from)); log.info("points to obj " PTR_FORMAT " in region " HR_FORMAT, p2i(obj), HR_FORMAT_PARAMS(to));
_containing_obj->print_on(gclog_or_tty); obj->print_on(log.info_stream());
gclog_or_tty->print_cr("points to obj " PTR_FORMAT " " log.info("Obj head CTE = %d, field CTE = %d.", cv_obj, cv_field);
"in region " HR_FORMAT, log.info("----------");
p2i(obj),
HR_FORMAT_PARAMS(to));
obj->print_on(gclog_or_tty);
gclog_or_tty->print_cr("Obj head CTE = %d, field CTE = %d.",
cv_obj, cv_field);
gclog_or_tty->print_cr("----------");
gclog_or_tty->flush();
_failures = true; _failures = true;
if (!failed) _n_failures++; if (!failed) _n_failures++;
} }
@ -766,13 +743,13 @@ void HeapRegion::verify(VerifyOption vo,
(vo == VerifyOption_G1UsePrevMarking && (vo == VerifyOption_G1UsePrevMarking &&
ClassLoaderDataGraph::unload_list_contains(klass)); ClassLoaderDataGraph::unload_list_contains(klass));
if (!is_metaspace_object) { if (!is_metaspace_object) {
gclog_or_tty->print_cr("klass " PTR_FORMAT " of object " PTR_FORMAT " " log_info(gc, verify)("klass " PTR_FORMAT " of object " PTR_FORMAT " "
"not metadata", p2i(klass), p2i(obj)); "not metadata", p2i(klass), p2i(obj));
*failures = true; *failures = true;
return; return;
} else if (!klass->is_klass()) { } else if (!klass->is_klass()) {
gclog_or_tty->print_cr("klass " PTR_FORMAT " of object " PTR_FORMAT " " log_info(gc, verify)("klass " PTR_FORMAT " of object " PTR_FORMAT " "
"not a klass", p2i(klass), p2i(obj)); "not a klass", p2i(klass), p2i(obj));
*failures = true; *failures = true;
return; return;
} else { } else {
@ -787,7 +764,7 @@ void HeapRegion::verify(VerifyOption vo,
} }
} }
} else { } else {
gclog_or_tty->print_cr(PTR_FORMAT " no an oop", p2i(obj)); log_info(gc, verify)(PTR_FORMAT " no an oop", p2i(obj));
*failures = true; *failures = true;
return; return;
} }
@ -803,13 +780,13 @@ void HeapRegion::verify(VerifyOption vo,
if (is_region_humongous) { if (is_region_humongous) {
oop obj = oop(this->humongous_start_region()->bottom()); oop obj = oop(this->humongous_start_region()->bottom());
if ((HeapWord*)obj > bottom() || (HeapWord*)obj + obj->size() < bottom()) { if ((HeapWord*)obj > bottom() || (HeapWord*)obj + obj->size() < bottom()) {
gclog_or_tty->print_cr("this humongous region is not part of its' humongous object " PTR_FORMAT, p2i(obj)); log_info(gc, verify)("this humongous region is not part of its' humongous object " PTR_FORMAT, p2i(obj));
} }
} }
if (!is_region_humongous && p != top()) { if (!is_region_humongous && p != top()) {
gclog_or_tty->print_cr("end of last object " PTR_FORMAT " " log_info(gc, verify)("end of last object " PTR_FORMAT " "
"does not match top " PTR_FORMAT, p2i(p), p2i(top())); "does not match top " PTR_FORMAT, p2i(p), p2i(top()));
*failures = true; *failures = true;
return; return;
} }
@ -823,9 +800,9 @@ void HeapRegion::verify(VerifyOption vo,
HeapWord* addr_1 = p; HeapWord* addr_1 = p;
HeapWord* b_start_1 = _offsets.block_start_const(addr_1); HeapWord* b_start_1 = _offsets.block_start_const(addr_1);
if (b_start_1 != p) { if (b_start_1 != p) {
gclog_or_tty->print_cr("BOT look up for top: " PTR_FORMAT " " log_info(gc, verify)("BOT look up for top: " PTR_FORMAT " "
" yielded " PTR_FORMAT ", expecting " PTR_FORMAT, " yielded " PTR_FORMAT ", expecting " PTR_FORMAT,
p2i(addr_1), p2i(b_start_1), p2i(p)); p2i(addr_1), p2i(b_start_1), p2i(p));
*failures = true; *failures = true;
return; return;
} }
@ -835,9 +812,9 @@ void HeapRegion::verify(VerifyOption vo,
if (addr_2 < the_end) { if (addr_2 < the_end) {
HeapWord* b_start_2 = _offsets.block_start_const(addr_2); HeapWord* b_start_2 = _offsets.block_start_const(addr_2);
if (b_start_2 != p) { if (b_start_2 != p) {
gclog_or_tty->print_cr("BOT look up for top + 1: " PTR_FORMAT " " log_info(gc, verify)("BOT look up for top + 1: " PTR_FORMAT " "
" yielded " PTR_FORMAT ", expecting " PTR_FORMAT, " yielded " PTR_FORMAT ", expecting " PTR_FORMAT,
p2i(addr_2), p2i(b_start_2), p2i(p)); p2i(addr_2), p2i(b_start_2), p2i(p));
*failures = true; *failures = true;
return; return;
} }
@ -849,9 +826,9 @@ void HeapRegion::verify(VerifyOption vo,
if (addr_3 < the_end) { if (addr_3 < the_end) {
HeapWord* b_start_3 = _offsets.block_start_const(addr_3); HeapWord* b_start_3 = _offsets.block_start_const(addr_3);
if (b_start_3 != p) { if (b_start_3 != p) {
gclog_or_tty->print_cr("BOT look up for top + diff: " PTR_FORMAT " " log_info(gc, verify)("BOT look up for top + diff: " PTR_FORMAT " "
" yielded " PTR_FORMAT ", expecting " PTR_FORMAT, " yielded " PTR_FORMAT ", expecting " PTR_FORMAT,
p2i(addr_3), p2i(b_start_3), p2i(p)); p2i(addr_3), p2i(b_start_3), p2i(p));
*failures = true; *failures = true;
return; return;
} }
@ -861,9 +838,9 @@ void HeapRegion::verify(VerifyOption vo,
HeapWord* addr_4 = the_end - 1; HeapWord* addr_4 = the_end - 1;
HeapWord* b_start_4 = _offsets.block_start_const(addr_4); HeapWord* b_start_4 = _offsets.block_start_const(addr_4);
if (b_start_4 != p) { if (b_start_4 != p) {
gclog_or_tty->print_cr("BOT look up for end - 1: " PTR_FORMAT " " log_info(gc, verify)("BOT look up for end - 1: " PTR_FORMAT " "
" yielded " PTR_FORMAT ", expecting " PTR_FORMAT, " yielded " PTR_FORMAT ", expecting " PTR_FORMAT,
p2i(addr_4), p2i(b_start_4), p2i(p)); p2i(addr_4), p2i(b_start_4), p2i(p));
*failures = true; *failures = true;
return; return;
} }
@ -914,7 +891,7 @@ void G1OffsetTableContigSpace::mangle_unused_area_complete() {
void G1OffsetTableContigSpace::print() const { void G1OffsetTableContigSpace::print() const {
print_short(); print_short();
gclog_or_tty->print_cr(" [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " tty->print_cr(" [" INTPTR_FORMAT ", " INTPTR_FORMAT ", "
INTPTR_FORMAT ", " INTPTR_FORMAT ")", INTPTR_FORMAT ", " INTPTR_FORMAT ")",
p2i(bottom()), p2i(top()), p2i(_offsets.threshold()), p2i(end())); p2i(bottom()), p2i(top()), p2i(_offsets.threshold()), p2i(end()));
} }

View file

@ -560,20 +560,13 @@ PerRegionTable* OtherRegionsTable::delete_region_table() {
void OtherRegionsTable::scrub(CardTableModRefBS* ctbs, void OtherRegionsTable::scrub(CardTableModRefBS* ctbs,
BitMap* region_bm, BitMap* card_bm) { BitMap* region_bm, BitMap* card_bm) {
// First eliminated garbage regions from the coarse map. // First eliminated garbage regions from the coarse map.
if (G1RSScrubVerbose) { log_develop_trace(gc, remset, scrub)("Scrubbing region %u:", _hr->hrm_index());
gclog_or_tty->print_cr("Scrubbing region %u:", _hr->hrm_index());
}
assert(_coarse_map.size() == region_bm->size(), "Precondition"); assert(_coarse_map.size() == region_bm->size(), "Precondition");
if (G1RSScrubVerbose) { log_develop_trace(gc, remset, scrub)(" Coarse map: before = " SIZE_FORMAT "...", _n_coarse_entries);
gclog_or_tty->print(" Coarse map: before = " SIZE_FORMAT "...",
_n_coarse_entries);
}
_coarse_map.set_intersection(*region_bm); _coarse_map.set_intersection(*region_bm);
_n_coarse_entries = _coarse_map.count_one_bits(); _n_coarse_entries = _coarse_map.count_one_bits();
if (G1RSScrubVerbose) { log_develop_trace(gc, remset, scrub)(" after = " SIZE_FORMAT ".", _n_coarse_entries);
gclog_or_tty->print_cr(" after = " SIZE_FORMAT ".", _n_coarse_entries);
}
// Now do the fine-grained maps. // Now do the fine-grained maps.
for (size_t i = 0; i < _max_fine_entries; i++) { for (size_t i = 0; i < _max_fine_entries; i++) {
@ -582,28 +575,19 @@ void OtherRegionsTable::scrub(CardTableModRefBS* ctbs,
while (cur != NULL) { while (cur != NULL) {
PerRegionTable* nxt = cur->collision_list_next(); PerRegionTable* nxt = cur->collision_list_next();
// If the entire region is dead, eliminate. // If the entire region is dead, eliminate.
if (G1RSScrubVerbose) { log_develop_trace(gc, remset, scrub)(" For other region %u:", cur->hr()->hrm_index());
gclog_or_tty->print_cr(" For other region %u:",
cur->hr()->hrm_index());
}
if (!region_bm->at((size_t) cur->hr()->hrm_index())) { if (!region_bm->at((size_t) cur->hr()->hrm_index())) {
*prev = nxt; *prev = nxt;
cur->set_collision_list_next(NULL); cur->set_collision_list_next(NULL);
_n_fine_entries--; _n_fine_entries--;
if (G1RSScrubVerbose) { log_develop_trace(gc, remset, scrub)(" deleted via region map.");
gclog_or_tty->print_cr(" deleted via region map.");
}
unlink_from_all(cur); unlink_from_all(cur);
PerRegionTable::free(cur); PerRegionTable::free(cur);
} else { } else {
// Do fine-grain elimination. // Do fine-grain elimination.
if (G1RSScrubVerbose) { log_develop_trace(gc, remset, scrub)(" occ: before = %4d.", cur->occupied());
gclog_or_tty->print(" occ: before = %4d.", cur->occupied());
}
cur->scrub(ctbs, card_bm); cur->scrub(ctbs, card_bm);
if (G1RSScrubVerbose) { log_develop_trace(gc, remset, scrub)(" after = %4d.", cur->occupied());
gclog_or_tty->print_cr(" after = %4d.", cur->occupied());
}
// Did that empty the table completely? // Did that empty the table completely?
if (cur->occupied() == 0) { if (cur->occupied() == 0) {
*prev = nxt; *prev = nxt;
@ -799,15 +783,15 @@ void HeapRegionRemSet::print() {
while (iter.has_next(card_index)) { while (iter.has_next(card_index)) {
HeapWord* card_start = HeapWord* card_start =
G1CollectedHeap::heap()->bot_shared()->address_for_index(card_index); G1CollectedHeap::heap()->bot_shared()->address_for_index(card_index);
gclog_or_tty->print_cr(" Card " PTR_FORMAT, p2i(card_start)); tty->print_cr(" Card " PTR_FORMAT, p2i(card_start));
} }
if (iter.n_yielded() != occupied()) { if (iter.n_yielded() != occupied()) {
gclog_or_tty->print_cr("Yielded disagrees with occupied:"); tty->print_cr("Yielded disagrees with occupied:");
gclog_or_tty->print_cr(" " SIZE_FORMAT_W(6) " yielded (" SIZE_FORMAT_W(6) tty->print_cr(" " SIZE_FORMAT_W(6) " yielded (" SIZE_FORMAT_W(6)
" coarse, " SIZE_FORMAT_W(6) " fine).", " coarse, " SIZE_FORMAT_W(6) " fine).",
iter.n_yielded(), iter.n_yielded(),
iter.n_yielded_coarse(), iter.n_yielded_fine()); iter.n_yielded_coarse(), iter.n_yielded_fine());
gclog_or_tty->print_cr(" " SIZE_FORMAT_W(6) " occ (" SIZE_FORMAT_W(6) tty->print_cr(" " SIZE_FORMAT_W(6) " occ (" SIZE_FORMAT_W(6)
" coarse, " SIZE_FORMAT_W(6) " fine).", " coarse, " SIZE_FORMAT_W(6) " fine).",
occupied(), occ_coarse(), occ_fine()); occupied(), occ_coarse(), occ_fine());
} }
@ -1071,7 +1055,7 @@ void HeapRegionRemSet::test() {
while (iter.has_next(card_index)) { while (iter.has_next(card_index)) {
HeapWord* card_start = HeapWord* card_start =
G1CollectedHeap::heap()->bot_shared()->address_for_index(card_index); G1CollectedHeap::heap()->bot_shared()->address_for_index(card_index);
gclog_or_tty->print_cr(" Card " PTR_FORMAT ".", p2i(card_start)); tty->print_cr(" Card " PTR_FORMAT ".", p2i(card_start));
sum++; sum++;
} }
guarantee(sum == 11 - 3 + 2048, "Failure"); guarantee(sum == 11 - 3 + 2048, "Failure");

View file

@ -86,7 +86,7 @@ class FromCardCache : public AllStatic {
static void invalidate(uint start_idx, size_t num_regions); static void invalidate(uint start_idx, size_t num_regions);
static void print(outputStream* out = gclog_or_tty) PRODUCT_RETURN; static void print(outputStream* out = tty) PRODUCT_RETURN;
static size_t static_mem_size() { static size_t static_mem_size() {
return _static_mem_size; return _static_mem_size;

View file

@ -261,24 +261,6 @@ void FreeRegionList::clear() {
_last = NULL; _last = NULL;
} }
void FreeRegionList::print_on(outputStream* out, bool print_contents) {
HeapRegionSetBase::print_on(out, print_contents);
out->print_cr(" Linking");
out->print_cr(" head : " PTR_FORMAT, p2i(_head));
out->print_cr(" tail : " PTR_FORMAT, p2i(_tail));
if (print_contents) {
out->print_cr(" Contents");
FreeRegionListIterator iter(this);
while (iter.more_available()) {
HeapRegion* hr = iter.get_next();
hr->print_on(out);
}
}
out->cr();
}
void FreeRegionList::verify_list() { void FreeRegionList::verify_list() {
HeapRegion* curr = _head; HeapRegion* curr = _head;
HeapRegion* prev1 = NULL; HeapRegion* prev1 = NULL;

View file

@ -250,8 +250,6 @@ public:
void remove_starting_at(HeapRegion* first, uint num_regions); void remove_starting_at(HeapRegion* first, uint num_regions);
virtual void verify(); virtual void verify();
virtual void print_on(outputStream* out, bool print_contents = false);
}; };
// Iterator class that provides a convenient way to iterate over the // Iterator class that provides a convenient way to iterate over the

View file

@ -199,9 +199,8 @@ void SATBMarkQueue::print(const char* name) {
void SATBMarkQueue::print(const char* name, void SATBMarkQueue::print(const char* name,
void** buf, size_t index, size_t sz) { void** buf, size_t index, size_t sz) {
gclog_or_tty->print_cr(" SATB BUFFER [%s] buf: " PTR_FORMAT " " tty->print_cr(" SATB BUFFER [%s] buf: " PTR_FORMAT " index: " SIZE_FORMAT " sz: " SIZE_FORMAT,
"index: " SIZE_FORMAT " sz: " SIZE_FORMAT, name, p2i(buf), index, sz);
name, p2i(buf), index, sz);
} }
#endif // PRODUCT #endif // PRODUCT
@ -222,16 +221,13 @@ void SATBMarkQueueSet::handle_zero_index_for_thread(JavaThread* t) {
#ifdef ASSERT #ifdef ASSERT
void SATBMarkQueueSet::dump_active_states(bool expected_active) { void SATBMarkQueueSet::dump_active_states(bool expected_active) {
gclog_or_tty->print_cr("Expected SATB active state: %s", log_info(gc, verify)("Expected SATB active state: %s", expected_active ? "ACTIVE" : "INACTIVE");
expected_active ? "ACTIVE" : "INACTIVE"); log_info(gc, verify)("Actual SATB active states:");
gclog_or_tty->print_cr("Actual SATB active states:"); log_info(gc, verify)(" Queue set: %s", is_active() ? "ACTIVE" : "INACTIVE");
gclog_or_tty->print_cr(" Queue set: %s", is_active() ? "ACTIVE" : "INACTIVE");
for (JavaThread* t = Threads::first(); t; t = t->next()) { for (JavaThread* t = Threads::first(); t; t = t->next()) {
gclog_or_tty->print_cr(" Thread \"%s\" queue: %s", t->name(), log_info(gc, verify)(" Thread \"%s\" queue: %s", t->name(), t->satb_mark_queue().is_active() ? "ACTIVE" : "INACTIVE");
t->satb_mark_queue().is_active() ? "ACTIVE" : "INACTIVE");
} }
gclog_or_tty->print_cr(" Shared queue: %s", log_info(gc, verify)(" Shared queue: %s", shared_satb_queue()->is_active() ? "ACTIVE" : "INACTIVE");
shared_satb_queue()->is_active() ? "ACTIVE" : "INACTIVE");
} }
void SATBMarkQueueSet::verify_active_states(bool expected_active) { void SATBMarkQueueSet::verify_active_states(bool expected_active) {
@ -318,8 +314,8 @@ void SATBMarkQueueSet::print_all(const char* msg) {
char buffer[SATB_PRINTER_BUFFER_SIZE]; char buffer[SATB_PRINTER_BUFFER_SIZE];
assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint."); assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
gclog_or_tty->cr(); tty->cr();
gclog_or_tty->print_cr("SATB BUFFERS [%s]", msg); tty->print_cr("SATB BUFFERS [%s]", msg);
BufferNode* nd = _completed_buffers_head; BufferNode* nd = _completed_buffers_head;
int i = 0; int i = 0;
@ -338,7 +334,7 @@ void SATBMarkQueueSet::print_all(const char* msg) {
shared_satb_queue()->print("Shared"); shared_satb_queue()->print("Shared");
gclog_or_tty->cr(); tty->cr();
} }
#endif // PRODUCT #endif // PRODUCT

View file

@ -27,6 +27,7 @@
#include "gc/g1/g1Predictions.hpp" #include "gc/g1/g1Predictions.hpp"
#include "gc/g1/heapRegion.hpp" #include "gc/g1/heapRegion.hpp"
#include "gc/g1/survRateGroup.hpp" #include "gc/g1/survRateGroup.hpp"
#include "logging/log.hpp"
#include "memory/allocation.hpp" #include "memory/allocation.hpp"
SurvRateGroup::SurvRateGroup(G1Predictions* predictor, SurvRateGroup::SurvRateGroup(G1Predictions* predictor,
@ -163,12 +164,11 @@ void SurvRateGroup::all_surviving_words_recorded(bool update_predictors) {
#ifndef PRODUCT #ifndef PRODUCT
void SurvRateGroup::print() { void SurvRateGroup::print() {
gclog_or_tty->print_cr("Surv Rate Group: %s (" SIZE_FORMAT " entries)", log_develop_trace(gc, survivor)("Surv Rate Group: %s (" SIZE_FORMAT " entries)", _name, _region_num);
_name, _region_num);
for (size_t i = 0; i < _region_num; ++i) { for (size_t i = 0; i < _region_num; ++i) {
gclog_or_tty->print_cr(" age " SIZE_FORMAT_W(4) " surv rate %6.2lf %% pred %6.2lf %%", log_develop_trace(gc, survivor)(" age " SIZE_FORMAT_W(4) " surv rate %6.2lf %% pred %6.2lf %%",
i, _surv_rate[i] * 100.0, i, _surv_rate[i] * 100.0,
_predictor->get_new_prediction(_surv_rate_pred[i]) * 100.0); _predictor->get_new_prediction(_surv_rate_pred[i]) * 100.0);
} }
} }
@ -178,22 +178,20 @@ SurvRateGroup::print_surv_rate_summary() {
if (length == 0) if (length == 0)
return; return;
gclog_or_tty->cr(); log_trace(gc, survivor)("%s Rate Summary (for up to age " SIZE_FORMAT ")", _name, length-1);
gclog_or_tty->print_cr("%s Rate Summary (for up to age " SIZE_FORMAT ")", _name, length-1); log_trace(gc, survivor)(" age range survival rate (avg) samples (avg)");
gclog_or_tty->print_cr(" age range survival rate (avg) samples (avg)"); log_trace(gc, survivor)(" ---------------------------------------------------------");
gclog_or_tty->print_cr(" ---------------------------------------------------------");
size_t index = 0; size_t index = 0;
size_t limit = MIN2((int) length, 10); size_t limit = MIN2((int) length, 10);
while (index < limit) { while (index < limit) {
gclog_or_tty->print_cr(" " SIZE_FORMAT_W(4) log_trace(gc, survivor)(" " SIZE_FORMAT_W(4) " %6.2lf%% %6.2lf",
" %6.2lf%% %6.2lf", index, _summary_surv_rates[index]->avg() * 100.0,
index, _summary_surv_rates[index]->avg() * 100.0, (double) _summary_surv_rates[index]->num());
(double) _summary_surv_rates[index]->num());
++index; ++index;
} }
gclog_or_tty->print_cr(" ---------------------------------------------------------"); log_trace(gc, survivor)(" ---------------------------------------------------------");
int num = 0; int num = 0;
double sum = 0.0; double sum = 0.0;
@ -205,16 +203,15 @@ SurvRateGroup::print_surv_rate_summary() {
++index; ++index;
if (index == length || num % 10 == 0) { if (index == length || num % 10 == 0) {
gclog_or_tty->print_cr(" " SIZE_FORMAT_W(4) " .. " SIZE_FORMAT_W(4) log_trace(gc, survivor)(" " SIZE_FORMAT_W(4) " .. " SIZE_FORMAT_W(4) " %6.2lf%% %6.2lf",
" %6.2lf%% %6.2lf", (index-1) / 10 * 10, index-1, sum / (double) num,
(index-1) / 10 * 10, index-1, sum / (double) num, (double) samples / (double) num);
(double) samples / (double) num);
sum = 0.0; sum = 0.0;
num = 0; num = 0;
samples = 0; samples = 0;
} }
} }
gclog_or_tty->print_cr(" ---------------------------------------------------------"); log_trace(gc, survivor)(" ---------------------------------------------------------");
} }
#endif // PRODUCT #endif // PRODUCT

View file

@ -27,10 +27,9 @@
#include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp"
#include "gc/g1/g1CollectorPolicy.hpp" #include "gc/g1/g1CollectorPolicy.hpp"
#include "gc/shared/gcId.hpp" #include "gc/shared/gcId.hpp"
#include "gc/g1/g1Log.hpp"
#include "gc/g1/vm_operations_g1.hpp" #include "gc/g1/vm_operations_g1.hpp"
#include "gc/shared/gcTimer.hpp" #include "gc/shared/gcTimer.hpp"
#include "gc/shared/gcTraceTime.hpp" #include "gc/shared/gcTraceTime.inline.hpp"
#include "gc/shared/isGCActiveMark.hpp" #include "gc/shared/isGCActiveMark.hpp"
#include "runtime/interfaceSupport.hpp" #include "runtime/interfaceSupport.hpp"
@ -226,10 +225,10 @@ void VM_CGC_Operation::release_and_notify_pending_list_lock() {
} }
void VM_CGC_Operation::doit() { void VM_CGC_Operation::doit() {
TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty);
G1CollectedHeap* g1h = G1CollectedHeap::heap();
GCIdMark gc_id_mark(_gc_id); GCIdMark gc_id_mark(_gc_id);
GCTraceTime t(_printGCMessage, G1Log::fine(), true, g1h->gc_timer_cm()); GCTraceCPUTime tcpu;
G1CollectedHeap* g1h = G1CollectedHeap::heap();
GCTraceTime(Info, gc) t(_printGCMessage, g1h->gc_timer_cm(), GCCause::_no_gc, true);
IsGCActiveMark x; IsGCActiveMark x;
_cl->do_void(); _cl->do_void();
} }

View file

@ -30,13 +30,11 @@ void WorkerDataArray_test() {
const uint length = 3; const uint length = 3;
const char* title = "Test array"; const char* title = "Test array";
const bool print_sum = false; const bool print_sum = false;
const int log_level = 3;
const uint indent_level = 2; const uint indent_level = 2;
WorkerDataArray<size_t> array(length, title, print_sum, log_level, indent_level); WorkerDataArray<size_t> array(length, title, print_sum, indent_level);
assert(strncmp(array.title(), title, strlen(title)) == 0 , "Expected titles to match"); assert(strncmp(array.title(), title, strlen(title)) == 0 , "Expected titles to match");
assert(array.should_print_sum() == print_sum, "Expected should_print_sum to match print_sum"); assert(array.should_print_sum() == print_sum, "Expected should_print_sum to match print_sum");
assert(array.log_level() == log_level, "Expected log levels to match");
assert(array.indentation() == indent_level, "Expected indentation to match"); assert(array.indentation() == indent_level, "Expected indentation to match");
const size_t expected[length] = {5, 3, 7}; const size_t expected[length] = {5, 3, 7};

View file

@ -32,7 +32,6 @@ class WorkerDataArray : public CHeapObj<mtGC> {
uint _length; uint _length;
const char* _title; const char* _title;
bool _print_sum; bool _print_sum;
int _log_level;
uint _indent_level; uint _indent_level;
bool _enabled; bool _enabled;
@ -46,7 +45,6 @@ class WorkerDataArray : public CHeapObj<mtGC> {
WorkerDataArray(uint length, WorkerDataArray(uint length,
const char* title, const char* title,
bool print_sum, bool print_sum,
int log_level,
uint indent_level); uint indent_level);
~WorkerDataArray(); ~WorkerDataArray();
@ -80,10 +78,6 @@ class WorkerDataArray : public CHeapObj<mtGC> {
return _print_sum; return _print_sum;
} }
int log_level() const {
return _log_level;
}
void clear(); void clear();
void set_enabled(bool enabled) { void set_enabled(bool enabled) {
_enabled = enabled; _enabled = enabled;

View file

@ -29,12 +29,10 @@ template <typename T>
WorkerDataArray<T>::WorkerDataArray(uint length, WorkerDataArray<T>::WorkerDataArray(uint length,
const char* title, const char* title,
bool print_sum, bool print_sum,
int log_level,
uint indent_level) : uint indent_level) :
_title(title), _title(title),
_length(0), _length(0),
_print_sum(print_sum), _print_sum(print_sum),
_log_level(log_level),
_indent_level(indent_level), _indent_level(indent_level),
_thread_work_items(NULL), _thread_work_items(NULL),
_enabled(true) { _enabled(true) {

View file

@ -29,6 +29,7 @@
#include "gc/g1/heapRegion.inline.hpp" #include "gc/g1/heapRegion.inline.hpp"
#include "gc/g1/heapRegionRemSet.hpp" #include "gc/g1/heapRegionRemSet.hpp"
#include "gc/g1/youngList.hpp" #include "gc/g1/youngList.hpp"
#include "logging/log.hpp"
#include "utilities/ostream.hpp" #include "utilities/ostream.hpp"
YoungList::YoungList(G1CollectedHeap* g1h) : YoungList::YoungList(G1CollectedHeap* g1h) :
@ -98,10 +99,10 @@ bool YoungList::check_list_well_formed() {
HeapRegion* last = NULL; HeapRegion* last = NULL;
while (curr != NULL) { while (curr != NULL) {
if (!curr->is_young()) { if (!curr->is_young()) {
gclog_or_tty->print_cr("### YOUNG REGION " PTR_FORMAT "-" PTR_FORMAT " " log_info(gc, verify)("### YOUNG REGION " PTR_FORMAT "-" PTR_FORMAT " "
"incorrectly tagged (y: %d, surv: %d)", "incorrectly tagged (y: %d, surv: %d)",
p2i(curr->bottom()), p2i(curr->end()), p2i(curr->bottom()), p2i(curr->end()),
curr->is_young(), curr->is_survivor()); curr->is_young(), curr->is_survivor());
ret = false; ret = false;
} }
++length; ++length;
@ -111,9 +112,8 @@ bool YoungList::check_list_well_formed() {
ret = ret && (length == _length); ret = ret && (length == _length);
if (!ret) { if (!ret) {
gclog_or_tty->print_cr("### YOUNG LIST seems not well formed!"); log_info(gc, verify)("### YOUNG LIST seems not well formed!");
gclog_or_tty->print_cr("### list has %u entries, _length is %u", log_info(gc, verify)("### list has %u entries, _length is %u", length, _length);
length, _length);
} }
return ret; return ret;
@ -123,20 +123,19 @@ bool YoungList::check_list_empty(bool check_sample) {
bool ret = true; bool ret = true;
if (_length != 0) { if (_length != 0) {
gclog_or_tty->print_cr("### YOUNG LIST should have 0 length, not %u", log_info(gc, verify)("### YOUNG LIST should have 0 length, not %u", _length);
_length);
ret = false; ret = false;
} }
if (check_sample && _last_sampled_rs_lengths != 0) { if (check_sample && _last_sampled_rs_lengths != 0) {
gclog_or_tty->print_cr("### YOUNG LIST has non-zero last sampled RS lengths"); log_info(gc, verify)("### YOUNG LIST has non-zero last sampled RS lengths");
ret = false; ret = false;
} }
if (_head != NULL) { if (_head != NULL) {
gclog_or_tty->print_cr("### YOUNG LIST does not have a NULL head"); log_info(gc, verify)("### YOUNG LIST does not have a NULL head");
ret = false; ret = false;
} }
if (!ret) { if (!ret) {
gclog_or_tty->print_cr("### YOUNG LIST does not seem empty"); log_info(gc, verify)("### YOUNG LIST does not seem empty");
} }
return ret; return ret;
@ -171,7 +170,6 @@ YoungList::rs_length_sampling_next() {
_curr = _curr->get_next_young_region(); _curr = _curr->get_next_young_region();
if (_curr == NULL) { if (_curr == NULL) {
_last_sampled_rs_lengths = _sampled_rs_lengths; _last_sampled_rs_lengths = _sampled_rs_lengths;
// gclog_or_tty->print_cr("last sampled RS lengths = %d", _last_sampled_rs_lengths);
} }
} }
@ -222,13 +220,13 @@ void YoungList::print() {
const char* names[] = {"YOUNG", "SURVIVOR"}; const char* names[] = {"YOUNG", "SURVIVOR"};
for (uint list = 0; list < ARRAY_SIZE(lists); ++list) { for (uint list = 0; list < ARRAY_SIZE(lists); ++list) {
gclog_or_tty->print_cr("%s LIST CONTENTS", names[list]); tty->print_cr("%s LIST CONTENTS", names[list]);
HeapRegion *curr = lists[list]; HeapRegion *curr = lists[list];
if (curr == NULL) { if (curr == NULL) {
gclog_or_tty->print_cr(" empty"); tty->print_cr(" empty");
} }
while (curr != NULL) { while (curr != NULL) {
gclog_or_tty->print_cr(" " HR_FORMAT ", P: " PTR_FORMAT ", N: " PTR_FORMAT ", age: %4d", tty->print_cr(" " HR_FORMAT ", P: " PTR_FORMAT ", N: " PTR_FORMAT ", age: %4d",
HR_FORMAT_PARAMS(curr), HR_FORMAT_PARAMS(curr),
p2i(curr->prev_top_at_mark_start()), p2i(curr->prev_top_at_mark_start()),
p2i(curr->next_top_at_mark_start()), p2i(curr->next_top_at_mark_start()),
@ -237,5 +235,5 @@ void YoungList::print() {
} }
} }
gclog_or_tty->cr(); tty->cr();
} }

View file

@ -27,6 +27,9 @@
#include "gc/parallel/adjoiningVirtualSpaces.hpp" #include "gc/parallel/adjoiningVirtualSpaces.hpp"
#include "gc/parallel/generationSizer.hpp" #include "gc/parallel/generationSizer.hpp"
#include "gc/parallel/parallelScavengeHeap.hpp" #include "gc/parallel/parallelScavengeHeap.hpp"
#include "logging/log.hpp"
#include "memory/resourceArea.hpp"
#include "utilities/ostream.hpp"
// If boundary moving is being used, create the young gen and old // If boundary moving is being used, create the young gen and old
// gen with ASPSYoungGen and ASPSOldGen, respectively. Revert to // gen with ASPSYoungGen and ASPSOldGen, respectively. Revert to
@ -116,6 +119,29 @@ size_t AdjoiningGenerations::reserved_byte_size() {
return virtual_spaces()->reserved_space().size(); return virtual_spaces()->reserved_space().size();
} }
void log_before_expansion(bool old, size_t expand_in_bytes, size_t change_in_bytes, size_t max_size) {
LogHandle(heap, ergo) log;
if (!log.is_debug()) {
return;
}
log.debug("Before expansion of %s gen with boundary move", old ? "old" : "young");
log.debug(" Requested change: " SIZE_FORMAT_HEX " Attempted change: " SIZE_FORMAT_HEX,
expand_in_bytes, change_in_bytes);
ResourceMark rm;
ParallelScavengeHeap::heap()->print_on(log.debug_stream());
log.debug(" PS%sGen max size: " SIZE_FORMAT "K", old ? "Old" : "Young", max_size/K);
}
void log_after_expansion(bool old, size_t max_size) {
LogHandle(heap, ergo) log;
if (!log.is_debug()) {
return;
}
log.debug("After expansion of %s gen with boundary move", old ? "old" : "young");
ResourceMark rm;
ParallelScavengeHeap::heap()->print_on(log.debug_stream());
log.debug(" PS%sGen max size: " SIZE_FORMAT "K", old ? "Old" : "Young", max_size/K);
}
// Make checks on the current sizes of the generations and // Make checks on the current sizes of the generations and
// the constraints on the sizes of the generations. Push // the constraints on the sizes of the generations. Push
@ -141,17 +167,7 @@ void AdjoiningGenerations::request_old_gen_expansion(size_t expand_in_bytes) {
return; return;
} }
if (TraceAdaptiveGCBoundary) { log_before_expansion(true, expand_in_bytes, change_in_bytes, old_gen()->max_gen_size());
gclog_or_tty->print_cr("Before expansion of old gen with boundary move");
gclog_or_tty->print_cr(" Requested change: " SIZE_FORMAT_HEX
" Attempted change: " SIZE_FORMAT_HEX,
expand_in_bytes, change_in_bytes);
if (!PrintHeapAtGC) {
Universe::print_on(gclog_or_tty);
}
gclog_or_tty->print_cr(" PSOldGen max size: " SIZE_FORMAT "K",
old_gen()->max_gen_size()/K);
}
// Move the boundary between the generations up (smaller young gen). // Move the boundary between the generations up (smaller young gen).
if (virtual_spaces()->adjust_boundary_up(change_in_bytes)) { if (virtual_spaces()->adjust_boundary_up(change_in_bytes)) {
@ -167,14 +183,7 @@ void AdjoiningGenerations::request_old_gen_expansion(size_t expand_in_bytes) {
young_gen()->space_invariants(); young_gen()->space_invariants();
old_gen()->space_invariants(); old_gen()->space_invariants();
if (TraceAdaptiveGCBoundary) { log_after_expansion(true, old_gen()->max_gen_size());
gclog_or_tty->print_cr("After expansion of old gen with boundary move");
if (!PrintHeapAtGC) {
Universe::print_on(gclog_or_tty);
}
gclog_or_tty->print_cr(" PSOldGen max size: " SIZE_FORMAT "K",
old_gen()->max_gen_size()/K);
}
} }
// See comments on request_old_gen_expansion() // See comments on request_old_gen_expansion()
@ -200,16 +209,7 @@ bool AdjoiningGenerations::request_young_gen_expansion(size_t expand_in_bytes) {
return false; return false;
} }
if (TraceAdaptiveGCBoundary) { log_before_expansion(false, expand_in_bytes, change_in_bytes, young_gen()->max_size());
gclog_or_tty->print_cr("Before expansion of young gen with boundary move");
gclog_or_tty->print_cr(" Requested change: " SIZE_FORMAT_HEX " Attempted change: " SIZE_FORMAT_HEX,
expand_in_bytes, change_in_bytes);
if (!PrintHeapAtGC) {
Universe::print_on(gclog_or_tty);
}
gclog_or_tty->print_cr(" PSYoungGen max size: " SIZE_FORMAT "K",
young_gen()->max_size()/K);
}
// Move the boundary between the generations down (smaller old gen). // Move the boundary between the generations down (smaller old gen).
MutexLocker x(ExpandHeap_lock); MutexLocker x(ExpandHeap_lock);
@ -227,14 +227,7 @@ bool AdjoiningGenerations::request_young_gen_expansion(size_t expand_in_bytes) {
young_gen()->space_invariants(); young_gen()->space_invariants();
old_gen()->space_invariants(); old_gen()->space_invariants();
if (TraceAdaptiveGCBoundary) { log_after_expansion(false, young_gen()->max_size());
gclog_or_tty->print_cr("After expansion of young gen with boundary move");
if (!PrintHeapAtGC) {
Universe::print_on(gclog_or_tty);
}
gclog_or_tty->print_cr(" PSYoungGen max size: " SIZE_FORMAT "K",
young_gen()->max_size()/K);
}
return result; return result;
} }

View file

@ -125,25 +125,21 @@ size_t ASPSOldGen::available_for_contraction() {
size_t result = policy->promo_increment_aligned_down(max_contraction); size_t result = policy->promo_increment_aligned_down(max_contraction);
// Also adjust for inter-generational alignment // Also adjust for inter-generational alignment
size_t result_aligned = align_size_down(result, gen_alignment); size_t result_aligned = align_size_down(result, gen_alignment);
if (PrintAdaptiveSizePolicy && Verbose) {
gclog_or_tty->print_cr("\nASPSOldGen::available_for_contraction:" LogHandle(gc, ergo) log;
" " SIZE_FORMAT " K / " SIZE_FORMAT_HEX, result_aligned/K, result_aligned); if (log.is_trace()) {
gclog_or_tty->print_cr(" reserved().byte_size() " SIZE_FORMAT " K / " SIZE_FORMAT_HEX,
reserved().byte_size()/K, reserved().byte_size());
size_t working_promoted = (size_t) policy->avg_promoted()->padded_average(); size_t working_promoted = (size_t) policy->avg_promoted()->padded_average();
gclog_or_tty->print_cr(" padded promoted " SIZE_FORMAT " K / " SIZE_FORMAT_HEX, size_t promo_increment = policy->promo_increment(max_contraction);
working_promoted/K, working_promoted); log.trace("ASPSOldGen::available_for_contraction: " SIZE_FORMAT " K / " SIZE_FORMAT_HEX, result_aligned/K, result_aligned);
gclog_or_tty->print_cr(" used " SIZE_FORMAT " K / " SIZE_FORMAT_HEX, log.trace(" reserved().byte_size() " SIZE_FORMAT " K / " SIZE_FORMAT_HEX, reserved().byte_size()/K, reserved().byte_size());
used_in_bytes()/K, used_in_bytes()); log.trace(" padded promoted " SIZE_FORMAT " K / " SIZE_FORMAT_HEX, working_promoted/K, working_promoted);
gclog_or_tty->print_cr(" min_gen_size() " SIZE_FORMAT " K / " SIZE_FORMAT_HEX, log.trace(" used " SIZE_FORMAT " K / " SIZE_FORMAT_HEX, used_in_bytes()/K, used_in_bytes());
min_gen_size()/K, min_gen_size()); log.trace(" min_gen_size() " SIZE_FORMAT " K / " SIZE_FORMAT_HEX, min_gen_size()/K, min_gen_size());
gclog_or_tty->print_cr(" max_contraction " SIZE_FORMAT " K / " SIZE_FORMAT_HEX, log.trace(" max_contraction " SIZE_FORMAT " K / " SIZE_FORMAT_HEX, max_contraction/K, max_contraction);
max_contraction/K, max_contraction); log.trace(" without alignment " SIZE_FORMAT " K / " SIZE_FORMAT_HEX, promo_increment/K, promo_increment);
gclog_or_tty->print_cr(" without alignment " SIZE_FORMAT " K / " SIZE_FORMAT_HEX, log.trace(" alignment " SIZE_FORMAT_HEX, gen_alignment);
policy->promo_increment(max_contraction)/K,
policy->promo_increment(max_contraction));
gclog_or_tty->print_cr(" alignment " SIZE_FORMAT_HEX, gen_alignment);
} }
assert(result_aligned <= max_contraction, "arithmetic is wrong"); assert(result_aligned <= max_contraction, "arithmetic is wrong");
return result_aligned; return result_aligned;
} }

View file

@ -111,13 +111,12 @@ size_t ASPSYoungGen::available_for_contraction() {
PSAdaptiveSizePolicy* policy = heap->size_policy(); PSAdaptiveSizePolicy* policy = heap->size_policy();
size_t result = policy->eden_increment_aligned_down(max_contraction); size_t result = policy->eden_increment_aligned_down(max_contraction);
size_t result_aligned = align_size_down(result, gen_alignment); size_t result_aligned = align_size_down(result, gen_alignment);
if (PrintAdaptiveSizePolicy && Verbose) {
gclog_or_tty->print_cr("ASPSYoungGen::available_for_contraction: " SIZE_FORMAT " K", log_trace(gc, ergo)("ASPSYoungGen::available_for_contraction: " SIZE_FORMAT " K", result_aligned/K);
result_aligned/K); log_trace(gc, ergo)(" max_contraction " SIZE_FORMAT " K", max_contraction/K);
gclog_or_tty->print_cr(" max_contraction " SIZE_FORMAT " K", max_contraction/K); log_trace(gc, ergo)(" eden_avail " SIZE_FORMAT " K", eden_avail/K);
gclog_or_tty->print_cr(" eden_avail " SIZE_FORMAT " K", eden_avail/K); log_trace(gc, ergo)(" gen_avail " SIZE_FORMAT " K", gen_avail/K);
gclog_or_tty->print_cr(" gen_avail " SIZE_FORMAT " K", gen_avail/K);
}
return result_aligned; return result_aligned;
} }
@ -199,25 +198,17 @@ bool ASPSYoungGen::resize_generation(size_t eden_size, size_t survivor_size) {
virtual_space()->shrink_by(change); virtual_space()->shrink_by(change);
size_changed = true; size_changed = true;
} else { } else {
if (Verbose && PrintGC) { if (orig_size == gen_size_limit()) {
if (orig_size == gen_size_limit()) { log_trace(gc)("ASPSYoung generation size at maximum: " SIZE_FORMAT "K", orig_size/K);
gclog_or_tty->print_cr("ASPSYoung generation size at maximum: " } else if (orig_size == min_gen_size()) {
SIZE_FORMAT "K", orig_size/K); log_trace(gc)("ASPSYoung generation size at minium: " SIZE_FORMAT "K", orig_size/K);
} else if (orig_size == min_gen_size()) {
gclog_or_tty->print_cr("ASPSYoung generation size at minium: "
SIZE_FORMAT "K", orig_size/K);
}
} }
} }
if (size_changed) { if (size_changed) {
reset_after_change(); reset_after_change();
if (Verbose && PrintGC) { log_trace(gc)("ASPSYoung generation size changed: " SIZE_FORMAT "K->" SIZE_FORMAT "K",
size_t current_size = virtual_space()->committed_size(); orig_size/K, virtual_space()->committed_size()/K);
gclog_or_tty->print_cr("ASPSYoung generation size changed: "
SIZE_FORMAT "K->" SIZE_FORMAT "K",
orig_size/K, current_size/K);
}
} }
guarantee(eden_plus_survivors <= virtual_space()->committed_size() || guarantee(eden_plus_survivors <= virtual_space()->committed_size() ||
@ -245,41 +236,31 @@ void ASPSYoungGen::resize_spaces(size_t requested_eden_size,
return; return;
} }
if (PrintAdaptiveSizePolicy && Verbose) { log_trace(gc, ergo)("PSYoungGen::resize_spaces(requested_eden_size: "
gclog_or_tty->print_cr("PSYoungGen::resize_spaces(requested_eden_size: " SIZE_FORMAT
SIZE_FORMAT ", requested_survivor_size: " SIZE_FORMAT ")",
", requested_survivor_size: " SIZE_FORMAT ")", requested_eden_size, requested_survivor_size);
requested_eden_size, requested_survivor_size); log_trace(gc, ergo)(" eden: [" PTR_FORMAT ".." PTR_FORMAT ") "
gclog_or_tty->print_cr(" eden: [" PTR_FORMAT ".." PTR_FORMAT ") " SIZE_FORMAT,
SIZE_FORMAT, p2i(eden_space()->bottom()),
p2i(eden_space()->bottom()), p2i(eden_space()->end()),
p2i(eden_space()->end()), pointer_delta(eden_space()->end(), eden_space()->bottom(), sizeof(char)));
pointer_delta(eden_space()->end(), log_trace(gc, ergo)(" from: [" PTR_FORMAT ".." PTR_FORMAT ") "
eden_space()->bottom(), SIZE_FORMAT,
sizeof(char))); p2i(from_space()->bottom()),
gclog_or_tty->print_cr(" from: [" PTR_FORMAT ".." PTR_FORMAT ") " p2i(from_space()->end()),
SIZE_FORMAT, pointer_delta(from_space()->end(), from_space()->bottom(), sizeof(char)));
p2i(from_space()->bottom()), log_trace(gc, ergo)(" to: [" PTR_FORMAT ".." PTR_FORMAT ") "
p2i(from_space()->end()), SIZE_FORMAT,
pointer_delta(from_space()->end(), p2i(to_space()->bottom()),
from_space()->bottom(), p2i(to_space()->end()),
sizeof(char))); pointer_delta( to_space()->end(), to_space()->bottom(), sizeof(char)));
gclog_or_tty->print_cr(" to: [" PTR_FORMAT ".." PTR_FORMAT ") "
SIZE_FORMAT,
p2i(to_space()->bottom()),
p2i(to_space()->end()),
pointer_delta( to_space()->end(),
to_space()->bottom(),
sizeof(char)));
}
// There's nothing to do if the new sizes are the same as the current // There's nothing to do if the new sizes are the same as the current
if (requested_survivor_size == to_space()->capacity_in_bytes() && if (requested_survivor_size == to_space()->capacity_in_bytes() &&
requested_survivor_size == from_space()->capacity_in_bytes() && requested_survivor_size == from_space()->capacity_in_bytes() &&
requested_eden_size == eden_space()->capacity_in_bytes()) { requested_eden_size == eden_space()->capacity_in_bytes()) {
if (PrintAdaptiveSizePolicy && Verbose) { log_trace(gc, ergo)(" capacities are the right sizes, returning");
gclog_or_tty->print_cr(" capacities are the right sizes, returning");
}
return; return;
} }
@ -302,9 +283,7 @@ void ASPSYoungGen::resize_spaces(size_t requested_eden_size,
if (eden_from_to_order) { if (eden_from_to_order) {
// Eden, from, to // Eden, from, to
if (PrintAdaptiveSizePolicy && Verbose) { log_trace(gc, ergo)(" Eden, from, to:");
gclog_or_tty->print_cr(" Eden, from, to:");
}
// Set eden // Set eden
// "requested_eden_size" is a goal for the size of eden // "requested_eden_size" is a goal for the size of eden
@ -368,28 +347,24 @@ void ASPSYoungGen::resize_spaces(size_t requested_eden_size,
guarantee(to_start != to_end, "to space is zero sized"); guarantee(to_start != to_end, "to space is zero sized");
if (PrintAdaptiveSizePolicy && Verbose) { log_trace(gc, ergo)(" [eden_start .. eden_end): "
gclog_or_tty->print_cr(" [eden_start .. eden_end): " "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
"[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, p2i(eden_start),
p2i(eden_start), p2i(eden_end),
p2i(eden_end), pointer_delta(eden_end, eden_start, sizeof(char)));
pointer_delta(eden_end, eden_start, sizeof(char))); log_trace(gc, ergo)(" [from_start .. from_end): "
gclog_or_tty->print_cr(" [from_start .. from_end): " "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
"[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, p2i(from_start),
p2i(from_start), p2i(from_end),
p2i(from_end), pointer_delta(from_end, from_start, sizeof(char)));
pointer_delta(from_end, from_start, sizeof(char))); log_trace(gc, ergo)(" [ to_start .. to_end): "
gclog_or_tty->print_cr(" [ to_start .. to_end): " "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
"[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, p2i(to_start),
p2i(to_start), p2i(to_end),
p2i(to_end), pointer_delta( to_end, to_start, sizeof(char)));
pointer_delta( to_end, to_start, sizeof(char)));
}
} else { } else {
// Eden, to, from // Eden, to, from
if (PrintAdaptiveSizePolicy && Verbose) { log_trace(gc, ergo)(" Eden, to, from:");
gclog_or_tty->print_cr(" Eden, to, from:");
}
// To space gets priority over eden resizing. Note that we position // To space gets priority over eden resizing. Note that we position
// to space as if we were able to resize from space, even though from // to space as if we were able to resize from space, even though from
@ -422,23 +397,21 @@ void ASPSYoungGen::resize_spaces(size_t requested_eden_size,
eden_end = MAX2(eden_end, eden_start + alignment); eden_end = MAX2(eden_end, eden_start + alignment);
to_start = MAX2(to_start, eden_end); to_start = MAX2(to_start, eden_end);
if (PrintAdaptiveSizePolicy && Verbose) { log_trace(gc, ergo)(" [eden_start .. eden_end): "
gclog_or_tty->print_cr(" [eden_start .. eden_end): " "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
"[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, p2i(eden_start),
p2i(eden_start), p2i(eden_end),
p2i(eden_end), pointer_delta(eden_end, eden_start, sizeof(char)));
pointer_delta(eden_end, eden_start, sizeof(char))); log_trace(gc, ergo)(" [ to_start .. to_end): "
gclog_or_tty->print_cr(" [ to_start .. to_end): " "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
"[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, p2i(to_start),
p2i(to_start), p2i(to_end),
p2i(to_end), pointer_delta( to_end, to_start, sizeof(char)));
pointer_delta( to_end, to_start, sizeof(char))); log_trace(gc, ergo)(" [from_start .. from_end): "
gclog_or_tty->print_cr(" [from_start .. from_end): " "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
"[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, p2i(from_start),
p2i(from_start), p2i(from_end),
p2i(from_end), pointer_delta(from_end, from_start, sizeof(char)));
pointer_delta(from_end, from_start, sizeof(char)));
}
} }
@ -457,7 +430,7 @@ void ASPSYoungGen::resize_spaces(size_t requested_eden_size,
// Let's make sure the call to initialize doesn't reset "top"! // Let's make sure the call to initialize doesn't reset "top"!
DEBUG_ONLY(HeapWord* old_from_top = from_space()->top();) DEBUG_ONLY(HeapWord* old_from_top = from_space()->top();)
// For PrintAdaptiveSizePolicy block below // For logging block below
size_t old_from = from_space()->capacity_in_bytes(); size_t old_from = from_space()->capacity_in_bytes();
size_t old_to = to_space()->capacity_in_bytes(); size_t old_to = to_space()->capacity_in_bytes();
@ -506,19 +479,16 @@ void ASPSYoungGen::resize_spaces(size_t requested_eden_size,
assert(from_space()->top() == old_from_top, "from top changed!"); assert(from_space()->top() == old_from_top, "from top changed!");
if (PrintAdaptiveSizePolicy) { log_trace(gc, ergo)("AdaptiveSizePolicy::survivor space sizes: "
ParallelScavengeHeap* heap = ParallelScavengeHeap::heap(); "collection: %d "
gclog_or_tty->print("AdaptiveSizePolicy::survivor space sizes: " "(" SIZE_FORMAT ", " SIZE_FORMAT ") -> "
"collection: %d " "(" SIZE_FORMAT ", " SIZE_FORMAT ") ",
"(" SIZE_FORMAT ", " SIZE_FORMAT ") -> " ParallelScavengeHeap::heap()->total_collections(),
"(" SIZE_FORMAT ", " SIZE_FORMAT ") ", old_from, old_to,
heap->total_collections(), from_space()->capacity_in_bytes(),
old_from, old_to, to_space()->capacity_in_bytes());
from_space()->capacity_in_bytes(),
to_space()->capacity_in_bytes()); space_invariants();
gclog_or_tty->cr();
}
space_invariants();
} }
void ASPSYoungGen::reset_after_change() { void ASPSYoungGen::reset_after_change() {
assert_locked_or_safepoint(Heap_lock); assert_locked_or_safepoint(Heap_lock);

View file

@ -468,30 +468,17 @@ void CardTableExtension::resize_covered_region_by_end(int changed_region,
// Update the covered region // Update the covered region
resize_update_covered_table(changed_region, new_region); resize_update_covered_table(changed_region, new_region);
if (TraceCardTableModRefBS) { int ind = changed_region;
int ind = changed_region; log_trace(gc, barrier)("CardTableModRefBS::resize_covered_region: ");
gclog_or_tty->print_cr("CardTableModRefBS::resize_covered_region: "); log_trace(gc, barrier)(" _covered[%d].start(): " INTPTR_FORMAT " _covered[%d].last(): " INTPTR_FORMAT,
gclog_or_tty->print_cr(" " ind, p2i(_covered[ind].start()), ind, p2i(_covered[ind].last()));
" _covered[%d].start(): " INTPTR_FORMAT log_trace(gc, barrier)(" _committed[%d].start(): " INTPTR_FORMAT " _committed[%d].last(): " INTPTR_FORMAT,
" _covered[%d].last(): " INTPTR_FORMAT, ind, p2i(_committed[ind].start()), ind, p2i(_committed[ind].last()));
ind, p2i(_covered[ind].start()), log_trace(gc, barrier)(" byte_for(start): " INTPTR_FORMAT " byte_for(last): " INTPTR_FORMAT,
ind, p2i(_covered[ind].last())); p2i(byte_for(_covered[ind].start())), p2i(byte_for(_covered[ind].last())));
gclog_or_tty->print_cr(" " log_trace(gc, barrier)(" addr_for(start): " INTPTR_FORMAT " addr_for(last): " INTPTR_FORMAT,
" _committed[%d].start(): " INTPTR_FORMAT p2i(addr_for((jbyte*) _committed[ind].start())), p2i(addr_for((jbyte*) _committed[ind].last())));
" _committed[%d].last(): " INTPTR_FORMAT,
ind, p2i(_committed[ind].start()),
ind, p2i(_committed[ind].last()));
gclog_or_tty->print_cr(" "
" byte_for(start): " INTPTR_FORMAT
" byte_for(last): " INTPTR_FORMAT,
p2i(byte_for(_covered[ind].start())),
p2i(byte_for(_covered[ind].last())));
gclog_or_tty->print_cr(" "
" addr_for(start): " INTPTR_FORMAT
" addr_for(last): " INTPTR_FORMAT,
p2i(addr_for((jbyte*) _committed[ind].start())),
p2i(addr_for((jbyte*) _committed[ind].last())));
}
debug_only(verify_guard();) debug_only(verify_guard();)
} }

View file

@ -27,6 +27,7 @@
#include "gc/parallel/gcTaskThread.hpp" #include "gc/parallel/gcTaskThread.hpp"
#include "gc/shared/adaptiveSizePolicy.hpp" #include "gc/shared/adaptiveSizePolicy.hpp"
#include "gc/shared/gcId.hpp" #include "gc/shared/gcId.hpp"
#include "logging/log.hpp"
#include "memory/allocation.hpp" #include "memory/allocation.hpp"
#include "memory/allocation.inline.hpp" #include "memory/allocation.inline.hpp"
#include "runtime/mutex.hpp" #include "runtime/mutex.hpp"
@ -465,13 +466,11 @@ void GCTaskManager::set_active_gang() {
"all_workers_active() is incorrect: " "all_workers_active() is incorrect: "
"active %d ParallelGCThreads %u", active_workers(), "active %d ParallelGCThreads %u", active_workers(),
ParallelGCThreads); ParallelGCThreads);
if (TraceDynamicGCThreads) { log_trace(gc, task)("GCTaskManager::set_active_gang(): "
gclog_or_tty->print_cr("GCTaskManager::set_active_gang(): " "all_workers_active() %d workers %d "
"all_workers_active() %d workers %d " "active %d ParallelGCThreads %u",
"active %d ParallelGCThreads %u", all_workers_active(), workers(), active_workers(),
all_workers_active(), workers(), active_workers(), ParallelGCThreads);
ParallelGCThreads);
}
} }
// Create IdleGCTasks for inactive workers. // Create IdleGCTasks for inactive workers.
@ -502,15 +501,12 @@ void GCTaskManager::task_idle_workers() {
set_active_workers(reduced_active_workers); set_active_workers(reduced_active_workers);
more_inactive_workers = 0; more_inactive_workers = 0;
} }
if (TraceDynamicGCThreads) { log_trace(gc, task)("JT: %d workers %d active %d idle %d more %d",
gclog_or_tty->print_cr("JT: %d workers %d active %d " Threads::number_of_non_daemon_threads(),
"idle %d more %d", workers(),
Threads::number_of_non_daemon_threads(), active_workers(),
workers(), idle_workers(),
active_workers(), more_inactive_workers);
idle_workers(),
more_inactive_workers);
}
} }
GCTaskQueue* q = GCTaskQueue::create(); GCTaskQueue* q = GCTaskQueue::create();
for(uint i = 0; i < (uint) more_inactive_workers; i++) { for(uint i = 0; i < (uint) more_inactive_workers; i++) {
@ -536,6 +532,9 @@ void GCTaskManager::release_idle_workers() {
} }
void GCTaskManager::print_task_time_stamps() { void GCTaskManager::print_task_time_stamps() {
if (!log_is_enabled(Debug, gc, task, time)) {
return;
}
for(uint i=0; i<ParallelGCThreads; i++) { for(uint i=0; i<ParallelGCThreads; i++) {
GCTaskThread* t = thread(i); GCTaskThread* t = thread(i);
t->print_task_time_stamps(); t->print_task_time_stamps();
@ -828,38 +827,24 @@ IdleGCTask* IdleGCTask::create_on_c_heap() {
void IdleGCTask::do_it(GCTaskManager* manager, uint which) { void IdleGCTask::do_it(GCTaskManager* manager, uint which) {
WaitHelper* wait_helper = manager->wait_helper(); WaitHelper* wait_helper = manager->wait_helper();
if (TraceGCTaskManager) { log_trace(gc, task)("[" INTPTR_FORMAT "] IdleGCTask:::do_it() should_wait: %s",
tty->print_cr("[" INTPTR_FORMAT "]"
" IdleGCTask:::do_it()"
" should_wait: %s",
p2i(this), wait_helper->should_wait() ? "true" : "false"); p2i(this), wait_helper->should_wait() ? "true" : "false");
}
MutexLockerEx ml(manager->monitor(), Mutex::_no_safepoint_check_flag); MutexLockerEx ml(manager->monitor(), Mutex::_no_safepoint_check_flag);
if (TraceDynamicGCThreads) { log_trace(gc, task)("--- idle %d", which);
gclog_or_tty->print_cr("--- idle %d", which);
}
// Increment has to be done when the idle tasks are created. // Increment has to be done when the idle tasks are created.
// manager->increment_idle_workers(); // manager->increment_idle_workers();
manager->monitor()->notify_all(); manager->monitor()->notify_all();
while (wait_helper->should_wait()) { while (wait_helper->should_wait()) {
if (TraceGCTaskManager) { log_trace(gc, task)("[" INTPTR_FORMAT "] IdleGCTask::do_it() [" INTPTR_FORMAT "] (%s)->wait()",
tty->print_cr("[" INTPTR_FORMAT "]" p2i(this), p2i(manager->monitor()), manager->monitor()->name());
" IdleGCTask::do_it()"
" [" INTPTR_FORMAT "] (%s)->wait()",
p2i(this), p2i(manager->monitor()), manager->monitor()->name());
}
manager->monitor()->wait(Mutex::_no_safepoint_check_flag, 0); manager->monitor()->wait(Mutex::_no_safepoint_check_flag, 0);
} }
manager->decrement_idle_workers(); manager->decrement_idle_workers();
if (TraceDynamicGCThreads) {
gclog_or_tty->print_cr("--- release %d", which); log_trace(gc, task)("--- release %d", which);
} log_trace(gc, task)("[" INTPTR_FORMAT "] IdleGCTask::do_it() returns should_wait: %s",
if (TraceGCTaskManager) { p2i(this), wait_helper->should_wait() ? "true" : "false");
tty->print_cr("[" INTPTR_FORMAT "]"
" IdleGCTask::do_it() returns"
" should_wait: %s",
p2i(this), wait_helper->should_wait() ? "true" : "false");
}
// Release monitor(). // Release monitor().
} }

View file

@ -26,9 +26,11 @@
#include "gc/parallel/gcTaskManager.hpp" #include "gc/parallel/gcTaskManager.hpp"
#include "gc/parallel/gcTaskThread.hpp" #include "gc/parallel/gcTaskThread.hpp"
#include "gc/shared/gcId.hpp" #include "gc/shared/gcId.hpp"
#include "logging/log.hpp"
#include "memory/allocation.hpp" #include "memory/allocation.hpp"
#include "memory/allocation.inline.hpp" #include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp" #include "memory/resourceArea.hpp"
#include "runtime/atomic.inline.hpp"
#include "runtime/handles.hpp" #include "runtime/handles.hpp"
#include "runtime/handles.inline.hpp" #include "runtime/handles.inline.hpp"
#include "runtime/os.hpp" #include "runtime/os.hpp"
@ -45,11 +47,6 @@ GCTaskThread::GCTaskThread(GCTaskManager* manager,
if (!os::create_thread(this, os::pgc_thread)) if (!os::create_thread(this, os::pgc_thread))
vm_exit_out_of_memory(0, OOM_MALLOC_ERROR, "Cannot create GC thread. Out of system resources."); vm_exit_out_of_memory(0, OOM_MALLOC_ERROR, "Cannot create GC thread. Out of system resources.");
if (PrintGCTaskTimeStamps) {
_time_stamps = NEW_C_HEAP_ARRAY(GCTaskTimeStamp, GCTaskTimeStampEntries, mtGC);
guarantee(_time_stamps != NULL, "Sanity");
}
set_id(which); set_id(which);
set_name("ParGC Thread#%d", which); set_name("ParGC Thread#%d", which);
} }
@ -66,21 +63,30 @@ void GCTaskThread::start() {
GCTaskTimeStamp* GCTaskThread::time_stamp_at(uint index) { GCTaskTimeStamp* GCTaskThread::time_stamp_at(uint index) {
guarantee(index < GCTaskTimeStampEntries, "increase GCTaskTimeStampEntries"); guarantee(index < GCTaskTimeStampEntries, "increase GCTaskTimeStampEntries");
if (_time_stamps == NULL) {
// We allocate the _time_stamps array lazily since logging can be enabled dynamically
GCTaskTimeStamp* time_stamps = NEW_C_HEAP_ARRAY(GCTaskTimeStamp, GCTaskTimeStampEntries, mtGC);
void* old = Atomic::cmpxchg_ptr(time_stamps, &_time_stamps, NULL);
if (old != NULL) {
// Someone already setup the time stamps
FREE_C_HEAP_ARRAY(GCTaskTimeStamp, time_stamps);
}
}
return &(_time_stamps[index]); return &(_time_stamps[index]);
} }
void GCTaskThread::print_task_time_stamps() { void GCTaskThread::print_task_time_stamps() {
assert(PrintGCTaskTimeStamps, "Sanity"); assert(log_is_enabled(Debug, gc, task, time), "Sanity");
assert(_time_stamps != NULL, "Sanity (Probably set PrintGCTaskTimeStamps late)"); assert(_time_stamps != NULL, "Sanity");
tty->print_cr("GC-Thread %u entries: %d", id(), _time_stamp_index); log_debug(gc, task, time)("GC-Thread %u entries: %d", id(), _time_stamp_index);
for(uint i=0; i<_time_stamp_index; i++) { for(uint i=0; i<_time_stamp_index; i++) {
GCTaskTimeStamp* time_stamp = time_stamp_at(i); GCTaskTimeStamp* time_stamp = time_stamp_at(i);
tty->print_cr("\t[ %s " JLONG_FORMAT " " JLONG_FORMAT " ]", log_debug(gc, task, time)("\t[ %s " JLONG_FORMAT " " JLONG_FORMAT " ]",
time_stamp->name(), time_stamp->name(),
time_stamp->entry_time(), time_stamp->entry_time(),
time_stamp->exit_time()); time_stamp->exit_time());
} }
// Reset after dumping the data // Reset after dumping the data
@ -127,7 +133,7 @@ void GCTaskThread::run() {
// Record if this is an idle task for later use. // Record if this is an idle task for later use.
bool is_idle_task = task->is_idle_task(); bool is_idle_task = task->is_idle_task();
// In case the update is costly // In case the update is costly
if (PrintGCTaskTimeStamps) { if (log_is_enabled(Debug, gc, task, time)) {
timer.update(); timer.update();
} }
@ -143,10 +149,7 @@ void GCTaskThread::run() {
if (!is_idle_task) { if (!is_idle_task) {
manager()->note_completion(which()); manager()->note_completion(which());
if (PrintGCTaskTimeStamps) { if (log_is_enabled(Debug, gc, task, time)) {
assert(_time_stamps != NULL,
"Sanity (PrintGCTaskTimeStamps set late?)");
timer.update(); timer.update();
GCTaskTimeStamp* time_stamp = time_stamp_at(_time_stamp_index++); GCTaskTimeStamp* time_stamp = time_stamp_at(_time_stamp_index++);

View file

@ -38,6 +38,7 @@
#include "gc/shared/gcHeapSummary.hpp" #include "gc/shared/gcHeapSummary.hpp"
#include "gc/shared/gcLocker.inline.hpp" #include "gc/shared/gcLocker.inline.hpp"
#include "gc/shared/gcWhen.hpp" #include "gc/shared/gcWhen.hpp"
#include "logging/log.hpp"
#include "oops/oop.inline.hpp" #include "oops/oop.inline.hpp"
#include "runtime/handles.inline.hpp" #include "runtime/handles.inline.hpp"
#include "runtime/java.hpp" #include "runtime/java.hpp"
@ -307,10 +308,7 @@ HeapWord* ParallelScavengeHeap::mem_allocate(
if (limit_exceeded && softrefs_clear) { if (limit_exceeded && softrefs_clear) {
*gc_overhead_limit_was_exceeded = true; *gc_overhead_limit_was_exceeded = true;
size_policy()->set_gc_overhead_limit_exceeded(false); size_policy()->set_gc_overhead_limit_exceeded(false);
if (PrintGCDetails && Verbose) { log_trace(gc)("ParallelScavengeHeap::mem_allocate: return NULL because gc_overhead_limit_exceeded is set");
gclog_or_tty->print_cr("ParallelScavengeHeap::mem_allocate: "
"return NULL because gc_overhead_limit_exceeded is set");
}
if (op.result() != NULL) { if (op.result() != NULL) {
CollectedHeap::fill_with_object(op.result(), size); CollectedHeap::fill_with_object(op.result(), size);
} }
@ -584,35 +582,17 @@ void ParallelScavengeHeap::print_tracing_info() const {
} }
void ParallelScavengeHeap::verify(bool silent, VerifyOption option /* ignored */) { void ParallelScavengeHeap::verify(VerifyOption option /* ignored */) {
// Why do we need the total_collections()-filter below? // Why do we need the total_collections()-filter below?
if (total_collections() > 0) { if (total_collections() > 0) {
if (!silent) { log_debug(gc, verify)("Tenured");
gclog_or_tty->print("tenured ");
}
old_gen()->verify(); old_gen()->verify();
if (!silent) { log_debug(gc, verify)("Eden");
gclog_or_tty->print("eden ");
}
young_gen()->verify(); young_gen()->verify();
} }
} }
void ParallelScavengeHeap::print_heap_change(size_t prev_used) {
if (PrintGCDetails && Verbose) {
gclog_or_tty->print(" " SIZE_FORMAT
"->" SIZE_FORMAT
"(" SIZE_FORMAT ")",
prev_used, used(), capacity());
} else {
gclog_or_tty->print(" " SIZE_FORMAT "K"
"->" SIZE_FORMAT "K"
"(" SIZE_FORMAT "K)",
prev_used / K, used() / K, capacity() / K);
}
}
void ParallelScavengeHeap::trace_heap(GCWhen::Type when, const GCTracer* gc_tracer) { void ParallelScavengeHeap::trace_heap(GCWhen::Type when, const GCTracer* gc_tracer) {
const PSHeapSummary& heap_summary = create_ps_heap_summary(); const PSHeapSummary& heap_summary = create_ps_heap_summary();
gc_tracer->report_gc_heap_summary(when, heap_summary); gc_tracer->report_gc_heap_summary(when, heap_summary);

View file

@ -35,6 +35,7 @@
#include "gc/shared/gcPolicyCounters.hpp" #include "gc/shared/gcPolicyCounters.hpp"
#include "gc/shared/gcWhen.hpp" #include "gc/shared/gcWhen.hpp"
#include "gc/shared/strongRootsScope.hpp" #include "gc/shared/strongRootsScope.hpp"
#include "memory/metaspace.hpp"
#include "utilities/ostream.hpp" #include "utilities/ostream.hpp"
class AdjoiningGenerations; class AdjoiningGenerations;
@ -87,6 +88,10 @@ class ParallelScavengeHeap : public CollectedHeap {
return CollectedHeap::ParallelScavengeHeap; return CollectedHeap::ParallelScavengeHeap;
} }
virtual const char* name() const {
return "Parallel";
}
virtual CollectorPolicy* collector_policy() const { return _collector_policy; } virtual CollectorPolicy* collector_policy() const { return _collector_policy; }
static PSYoungGen* young_gen() { return _young_gen; } static PSYoungGen* young_gen() { return _young_gen; }
@ -215,9 +220,7 @@ class ParallelScavengeHeap : public CollectedHeap {
virtual void gc_threads_do(ThreadClosure* tc) const; virtual void gc_threads_do(ThreadClosure* tc) const;
virtual void print_tracing_info() const; virtual void print_tracing_info() const;
void verify(bool silent, VerifyOption option /* ignored */); void verify(VerifyOption option /* ignored */);
void print_heap_change(size_t prev_used);
// Resize the young generation. The reserved space for the // Resize the young generation. The reserved space for the
// generation may be expanded in preparation for the resize. // generation may be expanded in preparation for the resize.
@ -241,4 +244,26 @@ class ParallelScavengeHeap : public CollectedHeap {
}; };
}; };
// Simple class for storing info about the heap at the start of GC, to be used
// after GC for comparison/printing.
class PreGCValues {
public:
PreGCValues(ParallelScavengeHeap* heap) :
_heap_used(heap->used()),
_young_gen_used(heap->young_gen()->used_in_bytes()),
_old_gen_used(heap->old_gen()->used_in_bytes()),
_metadata_used(MetaspaceAux::used_bytes()) { };
size_t heap_used() const { return _heap_used; }
size_t young_gen_used() const { return _young_gen_used; }
size_t old_gen_used() const { return _old_gen_used; }
size_t metadata_used() const { return _metadata_used; }
private:
size_t _heap_used;
size_t _young_gen_used;
size_t _old_gen_used;
size_t _metadata_used;
};
#endif // SHARE_VM_GC_PARALLEL_PARALLELSCAVENGEHEAP_HPP #endif // SHARE_VM_GC_PARALLEL_PARALLELSCAVENGEHEAP_HPP

View file

@ -31,7 +31,8 @@
#include "gc/parallel/psParallelCompact.hpp" #include "gc/parallel/psParallelCompact.hpp"
#include "gc/shared/collectedHeap.hpp" #include "gc/shared/collectedHeap.hpp"
#include "gc/shared/gcTimer.hpp" #include "gc/shared/gcTimer.hpp"
#include "gc/shared/gcTraceTime.hpp" #include "gc/shared/gcTraceTime.inline.hpp"
#include "logging/log.hpp"
#include "memory/universe.hpp" #include "memory/universe.hpp"
#include "oops/objArrayKlass.inline.hpp" #include "oops/objArrayKlass.inline.hpp"
#include "oops/oop.inline.hpp" #include "oops/oop.inline.hpp"
@ -251,14 +252,6 @@ void StealRegionCompactionTask::do_it(GCTaskManager* manager, uint which) {
cm->set_region_stack_index(which_stack_index); cm->set_region_stack_index(which_stack_index);
cm->set_region_stack(ParCompactionManager::region_list(which_stack_index)); cm->set_region_stack(ParCompactionManager::region_list(which_stack_index));
if (TraceDynamicGCThreads) {
gclog_or_tty->print_cr("StealRegionCompactionTask::do_it "
"region_stack_index %d region_stack = " PTR_FORMAT " "
" empty (%d) use all workers %d",
which_stack_index, p2i(ParCompactionManager::region_list(which_stack_index)),
cm->region_stack()->is_empty(),
use_all_workers);
}
// Has to drain stacks first because there may be regions on // Has to drain stacks first because there may be regions on
// preloaded onto the stack and this thread may never have // preloaded onto the stack and this thread may never have
@ -323,14 +316,6 @@ void DrainStacksCompactionTask::do_it(GCTaskManager* manager, uint which) {
} }
cm->set_region_stack(ParCompactionManager::region_list(which_stack_index)); cm->set_region_stack(ParCompactionManager::region_list(which_stack_index));
if (TraceDynamicGCThreads) {
gclog_or_tty->print_cr("DrainStacksCompactionTask::do_it which = %d "
"which_stack_index = %d/empty(%d) "
"use all workers %d",
which, which_stack_index,
cm->region_stack()->is_empty(),
use_all_workers);
}
cm->set_region_stack_index(which_stack_index); cm->set_region_stack_index(which_stack_index);
@ -346,13 +331,6 @@ void DrainStacksCompactionTask::do_it(GCTaskManager* manager, uint which) {
"region_stack and region_stack_index are inconsistent"); "region_stack and region_stack_index are inconsistent");
ParCompactionManager::push_recycled_stack_index(cm->region_stack_index()); ParCompactionManager::push_recycled_stack_index(cm->region_stack_index());
if (TraceDynamicGCThreads) {
void* old_region_stack = (void*) cm->region_stack();
int old_region_stack_index = cm->region_stack_index();
gclog_or_tty->print_cr("Pushing region stack " PTR_FORMAT "/%d",
p2i(old_region_stack), old_region_stack_index);
}
cm->set_region_stack(NULL); cm->set_region_stack(NULL);
cm->set_region_stack_index((uint)max_uintx); cm->set_region_stack_index((uint)max_uintx);
} }

View file

@ -30,6 +30,7 @@
#include "gc/shared/collectorPolicy.hpp" #include "gc/shared/collectorPolicy.hpp"
#include "gc/shared/gcCause.hpp" #include "gc/shared/gcCause.hpp"
#include "gc/shared/gcPolicyCounters.hpp" #include "gc/shared/gcPolicyCounters.hpp"
#include "logging/log.hpp"
#include "runtime/timer.hpp" #include "runtime/timer.hpp"
#include "utilities/top.hpp" #include "utilities/top.hpp"
@ -159,14 +160,10 @@ void PSAdaptiveSizePolicy::major_collection_end(size_t amount_live,
_major_pause_young_estimator->update(eden_size_in_mbytes, _major_pause_young_estimator->update(eden_size_in_mbytes,
major_pause_in_ms); major_pause_in_ms);
if (PrintAdaptiveSizePolicy && Verbose) { log_trace(gc, ergo)("psAdaptiveSizePolicy::major_collection_end: major gc cost: %f average: %f",
gclog_or_tty->print("psAdaptiveSizePolicy::major_collection_end: " collection_cost,avg_major_gc_cost()->average());
"major gc cost: %f average: %f", collection_cost, log_trace(gc, ergo)(" major pause: %f major period %f",
avg_major_gc_cost()->average()); major_pause_in_ms, _latest_major_mutator_interval_seconds * MILLIUNITS);
gclog_or_tty->print_cr(" major pause: %f major period %f",
major_pause_in_ms,
_latest_major_mutator_interval_seconds * MILLIUNITS);
}
// Calculate variable used to estimate collection cost vs. gen sizes // Calculate variable used to estimate collection cost vs. gen sizes
assert(collection_cost >= 0.0, "Expected to be non-negative"); assert(collection_cost >= 0.0, "Expected to be non-negative");
@ -197,19 +194,11 @@ bool PSAdaptiveSizePolicy::should_full_GC(size_t old_free_in_bytes) {
// A similar test is done in the scavenge's should_attempt_scavenge(). If // A similar test is done in the scavenge's should_attempt_scavenge(). If
// this is changed, decide if that test should also be changed. // this is changed, decide if that test should also be changed.
bool result = padded_average_promoted_in_bytes() > (float) old_free_in_bytes; bool result = padded_average_promoted_in_bytes() > (float) old_free_in_bytes;
if (PrintGCDetails && Verbose) { log_trace(gc, ergo)("%s after scavenge average_promoted " SIZE_FORMAT " padded_average_promoted " SIZE_FORMAT " free in old gen " SIZE_FORMAT,
if (result) { result ? "Full" : "No full",
gclog_or_tty->print(" full after scavenge: "); (size_t) average_promoted_in_bytes(),
} else { (size_t) padded_average_promoted_in_bytes(),
gclog_or_tty->print(" no full after scavenge: "); old_free_in_bytes);
}
gclog_or_tty->print_cr(" average_promoted " SIZE_FORMAT
" padded_average_promoted " SIZE_FORMAT
" free in old gen " SIZE_FORMAT,
(size_t) average_promoted_in_bytes(),
(size_t) padded_average_promoted_in_bytes(),
old_free_in_bytes);
}
return result; return result;
} }
@ -361,26 +350,24 @@ void PSAdaptiveSizePolicy::compute_eden_space_size(
// Note we make the same tests as in the code block below; the code // Note we make the same tests as in the code block below; the code
// seems a little easier to read with the printing in another block. // seems a little easier to read with the printing in another block.
if (PrintAdaptiveSizePolicy) { if (desired_eden_size > eden_limit) {
if (desired_eden_size > eden_limit) { log_debug(gc, ergo)(
gclog_or_tty->print_cr( "PSAdaptiveSizePolicy::compute_eden_space_size limits:"
"PSAdaptiveSizePolicy::compute_eden_space_size limits:" " desired_eden_size: " SIZE_FORMAT
" desired_eden_size: " SIZE_FORMAT " old_eden_size: " SIZE_FORMAT
" old_eden_size: " SIZE_FORMAT " eden_limit: " SIZE_FORMAT
" eden_limit: " SIZE_FORMAT " cur_eden: " SIZE_FORMAT
" cur_eden: " SIZE_FORMAT " max_eden_size: " SIZE_FORMAT
" max_eden_size: " SIZE_FORMAT " avg_young_live: " SIZE_FORMAT,
" avg_young_live: " SIZE_FORMAT, desired_eden_size, _eden_size, eden_limit, cur_eden,
desired_eden_size, _eden_size, eden_limit, cur_eden, max_eden_size, (size_t)avg_young_live()->average());
max_eden_size, (size_t)avg_young_live()->average()); }
} if (gc_cost() > gc_cost_limit) {
if (gc_cost() > gc_cost_limit) { log_debug(gc, ergo)(
gclog_or_tty->print_cr( "PSAdaptiveSizePolicy::compute_eden_space_size: gc time limit"
"PSAdaptiveSizePolicy::compute_eden_space_size: gc time limit" " gc_cost: %f "
" gc_cost: %f " " GCTimeLimit: " UINTX_FORMAT,
" GCTimeLimit: " UINTX_FORMAT, gc_cost(), GCTimeLimit);
gc_cost(), GCTimeLimit);
}
} }
// Align everything and make a final limit check // Align everything and make a final limit check
@ -399,51 +386,26 @@ void PSAdaptiveSizePolicy::compute_eden_space_size(
desired_eden_size = MAX2(eden_limit, cur_eden); desired_eden_size = MAX2(eden_limit, cur_eden);
} }
if (PrintAdaptiveSizePolicy) { log_debug(gc, ergo)("PSAdaptiveSizePolicy::compute_eden_space_size: costs minor_time: %f major_cost: %f mutator_cost: %f throughput_goal: %f",
// Timing stats minor_gc_cost(), major_gc_cost(), mutator_cost(), _throughput_goal);
gclog_or_tty->print(
"PSAdaptiveSizePolicy::compute_eden_space_size: costs"
" minor_time: %f"
" major_cost: %f"
" mutator_cost: %f"
" throughput_goal: %f",
minor_gc_cost(), major_gc_cost(), mutator_cost(),
_throughput_goal);
// We give more details if Verbose is set log_trace(gc, ergo)("Minor_pause: %f major_pause: %f minor_interval: %f major_interval: %fpause_goal: %f",
if (Verbose) { _avg_minor_pause->padded_average(),
gclog_or_tty->print( " minor_pause: %f" _avg_major_pause->padded_average(),
" major_pause: %f" _avg_minor_interval->average(),
" minor_interval: %f" _avg_major_interval->average(),
" major_interval: %f" gc_pause_goal_sec());
" pause_goal: %f",
_avg_minor_pause->padded_average(),
_avg_major_pause->padded_average(),
_avg_minor_interval->average(),
_avg_major_interval->average(),
gc_pause_goal_sec());
}
// Footprint stats log_debug(gc, ergo)("Live_space: " SIZE_FORMAT " free_space: " SIZE_FORMAT,
gclog_or_tty->print( " live_space: " SIZE_FORMAT live_space(), free_space());
" free_space: " SIZE_FORMAT,
live_space(), free_space());
// More detail
if (Verbose) {
gclog_or_tty->print( " base_footprint: " SIZE_FORMAT
" avg_young_live: " SIZE_FORMAT
" avg_old_live: " SIZE_FORMAT,
(size_t)_avg_base_footprint->average(),
(size_t)avg_young_live()->average(),
(size_t)avg_old_live()->average());
}
// And finally, our old and new sizes. log_trace(gc, ergo)("Base_footprint: " SIZE_FORMAT " avg_young_live: " SIZE_FORMAT " avg_old_live: " SIZE_FORMAT,
gclog_or_tty->print(" old_eden_size: " SIZE_FORMAT (size_t)_avg_base_footprint->average(),
" desired_eden_size: " SIZE_FORMAT, (size_t)avg_young_live()->average(),
_eden_size, desired_eden_size); (size_t)avg_old_live()->average());
gclog_or_tty->cr();
} log_debug(gc, ergo)("Old eden_size: " SIZE_FORMAT " desired_eden_size: " SIZE_FORMAT,
_eden_size, desired_eden_size);
set_eden_size(desired_eden_size); set_eden_size(desired_eden_size);
} }
@ -564,27 +526,25 @@ void PSAdaptiveSizePolicy::compute_old_gen_free_space(
// Note we make the same tests as in the code block below; the code // Note we make the same tests as in the code block below; the code
// seems a little easier to read with the printing in another block. // seems a little easier to read with the printing in another block.
if (PrintAdaptiveSizePolicy) { if (desired_promo_size > promo_limit) {
if (desired_promo_size > promo_limit) { // "free_in_old_gen" was the original value for used for promo_limit
// "free_in_old_gen" was the original value for used for promo_limit size_t free_in_old_gen = (size_t)(max_old_gen_size - avg_old_live()->average());
size_t free_in_old_gen = (size_t)(max_old_gen_size - avg_old_live()->average()); log_debug(gc, ergo)(
gclog_or_tty->print_cr( "PSAdaptiveSizePolicy::compute_old_gen_free_space limits:"
"PSAdaptiveSizePolicy::compute_old_gen_free_space limits:" " desired_promo_size: " SIZE_FORMAT
" desired_promo_size: " SIZE_FORMAT " promo_limit: " SIZE_FORMAT
" promo_limit: " SIZE_FORMAT " free_in_old_gen: " SIZE_FORMAT
" free_in_old_gen: " SIZE_FORMAT " max_old_gen_size: " SIZE_FORMAT
" max_old_gen_size: " SIZE_FORMAT " avg_old_live: " SIZE_FORMAT,
" avg_old_live: " SIZE_FORMAT, desired_promo_size, promo_limit, free_in_old_gen,
desired_promo_size, promo_limit, free_in_old_gen, max_old_gen_size, (size_t) avg_old_live()->average());
max_old_gen_size, (size_t) avg_old_live()->average()); }
} if (gc_cost() > gc_cost_limit) {
if (gc_cost() > gc_cost_limit) { log_debug(gc, ergo)(
gclog_or_tty->print_cr( "PSAdaptiveSizePolicy::compute_old_gen_free_space: gc time limit"
"PSAdaptiveSizePolicy::compute_old_gen_free_space: gc time limit" " gc_cost: %f "
" gc_cost: %f " " GCTimeLimit: " UINTX_FORMAT,
" GCTimeLimit: " UINTX_FORMAT, gc_cost(), GCTimeLimit);
gc_cost(), GCTimeLimit);
}
} }
// Align everything and make a final limit check // Align everything and make a final limit check
@ -596,51 +556,28 @@ void PSAdaptiveSizePolicy::compute_old_gen_free_space(
// And one last limit check, now that we've aligned things. // And one last limit check, now that we've aligned things.
desired_promo_size = MIN2(desired_promo_size, promo_limit); desired_promo_size = MIN2(desired_promo_size, promo_limit);
if (PrintAdaptiveSizePolicy) { // Timing stats
// Timing stats log_debug(gc, ergo)("PSAdaptiveSizePolicy::compute_old_gen_free_space: costs minor_time: %f major_cost: %f mutator_cost: %f throughput_goal: %f",
gclog_or_tty->print( minor_gc_cost(), major_gc_cost(), mutator_cost(), _throughput_goal);
"PSAdaptiveSizePolicy::compute_old_gen_free_space: costs"
" minor_time: %f"
" major_cost: %f"
" mutator_cost: %f"
" throughput_goal: %f",
minor_gc_cost(), major_gc_cost(), mutator_cost(),
_throughput_goal);
// We give more details if Verbose is set log_trace(gc, ergo)("Minor_pause: %f major_pause: %f minor_interval: %f major_interval: %f pause_goal: %f",
if (Verbose) { _avg_minor_pause->padded_average(),
gclog_or_tty->print( " minor_pause: %f" _avg_major_pause->padded_average(),
" major_pause: %f" _avg_minor_interval->average(),
" minor_interval: %f" _avg_major_interval->average(),
" major_interval: %f" gc_pause_goal_sec());
" pause_goal: %f",
_avg_minor_pause->padded_average(),
_avg_major_pause->padded_average(),
_avg_minor_interval->average(),
_avg_major_interval->average(),
gc_pause_goal_sec());
}
// Footprint stats // Footprint stats
gclog_or_tty->print( " live_space: " SIZE_FORMAT log_debug(gc, ergo)("Live_space: " SIZE_FORMAT " free_space: " SIZE_FORMAT,
" free_space: " SIZE_FORMAT, live_space(), free_space());
live_space(), free_space());
// More detail
if (Verbose) {
gclog_or_tty->print( " base_footprint: " SIZE_FORMAT
" avg_young_live: " SIZE_FORMAT
" avg_old_live: " SIZE_FORMAT,
(size_t)_avg_base_footprint->average(),
(size_t)avg_young_live()->average(),
(size_t)avg_old_live()->average());
}
// And finally, our old and new sizes. log_trace(gc, ergo)("Base_footprint: " SIZE_FORMAT " avg_young_live: " SIZE_FORMAT " avg_old_live: " SIZE_FORMAT,
gclog_or_tty->print(" old_promo_size: " SIZE_FORMAT (size_t)_avg_base_footprint->average(),
" desired_promo_size: " SIZE_FORMAT, (size_t)avg_young_live()->average(),
_promo_size, desired_promo_size); (size_t)avg_old_live()->average());
gclog_or_tty->cr();
} log_debug(gc, ergo)("Old promo_size: " SIZE_FORMAT " desired_promo_size: " SIZE_FORMAT,
_promo_size, desired_promo_size);
set_promo_size(desired_promo_size); set_promo_size(desired_promo_size);
} }
@ -719,14 +656,12 @@ void PSAdaptiveSizePolicy::adjust_promo_for_pause_time(bool is_full_gc,
} }
} }
if (PrintAdaptiveSizePolicy && Verbose) { log_trace(gc, ergo)(
gclog_or_tty->print_cr( "PSAdaptiveSizePolicy::adjust_promo_for_pause_time "
"PSAdaptiveSizePolicy::adjust_promo_for_pause_time " "adjusting gen sizes for major pause (avg %f goal %f). "
"adjusting gen sizes for major pause (avg %f goal %f). " "desired_promo_size " SIZE_FORMAT " promo delta " SIZE_FORMAT,
"desired_promo_size " SIZE_FORMAT " promo delta " SIZE_FORMAT, _avg_major_pause->average(), gc_pause_goal_sec(),
_avg_major_pause->average(), gc_pause_goal_sec(), *desired_promo_size_ptr, promo_heap_delta);
*desired_promo_size_ptr, promo_heap_delta);
}
} }
void PSAdaptiveSizePolicy::adjust_eden_for_pause_time(bool is_full_gc, void PSAdaptiveSizePolicy::adjust_eden_for_pause_time(bool is_full_gc,
@ -740,14 +675,12 @@ void PSAdaptiveSizePolicy::adjust_eden_for_pause_time(bool is_full_gc,
if (_avg_minor_pause->padded_average() > _avg_major_pause->padded_average()) { if (_avg_minor_pause->padded_average() > _avg_major_pause->padded_average()) {
adjust_eden_for_minor_pause_time(is_full_gc, desired_eden_size_ptr); adjust_eden_for_minor_pause_time(is_full_gc, desired_eden_size_ptr);
} }
if (PrintAdaptiveSizePolicy && Verbose) { log_trace(gc, ergo)(
gclog_or_tty->print_cr( "PSAdaptiveSizePolicy::adjust_eden_for_pause_time "
"PSAdaptiveSizePolicy::adjust_eden_for_pause_time " "adjusting gen sizes for major pause (avg %f goal %f). "
"adjusting gen sizes for major pause (avg %f goal %f). " "desired_eden_size " SIZE_FORMAT " eden delta " SIZE_FORMAT,
"desired_eden_size " SIZE_FORMAT " eden delta " SIZE_FORMAT, _avg_major_pause->average(), gc_pause_goal_sec(),
_avg_major_pause->average(), gc_pause_goal_sec(), *desired_eden_size_ptr, eden_heap_delta);
*desired_eden_size_ptr, eden_heap_delta);
}
} }
void PSAdaptiveSizePolicy::adjust_promo_for_throughput(bool is_full_gc, void PSAdaptiveSizePolicy::adjust_promo_for_throughput(bool is_full_gc,
@ -761,13 +694,8 @@ void PSAdaptiveSizePolicy::adjust_promo_for_throughput(bool is_full_gc,
return; return;
} }
if (PrintAdaptiveSizePolicy && Verbose) { log_trace(gc, ergo)("PSAdaptiveSizePolicy::adjust_promo_for_throughput(is_full: %d, promo: " SIZE_FORMAT "): mutator_cost %f major_gc_cost %f minor_gc_cost %f",
gclog_or_tty->print("\nPSAdaptiveSizePolicy::adjust_promo_for_throughput(" is_full_gc, *desired_promo_size_ptr, mutator_cost(), major_gc_cost(), minor_gc_cost());
"is_full: %d, promo: " SIZE_FORMAT "): ",
is_full_gc, *desired_promo_size_ptr);
gclog_or_tty->print_cr("mutator_cost %f major_gc_cost %f "
"minor_gc_cost %f", mutator_cost(), major_gc_cost(), minor_gc_cost());
}
// Tenured generation // Tenured generation
if (is_full_gc) { if (is_full_gc) {
@ -780,12 +708,8 @@ void PSAdaptiveSizePolicy::adjust_promo_for_throughput(bool is_full_gc,
double scale_by_ratio = major_gc_cost() / gc_cost(); double scale_by_ratio = major_gc_cost() / gc_cost();
scaled_promo_heap_delta = scaled_promo_heap_delta =
(size_t) (scale_by_ratio * (double) promo_heap_delta); (size_t) (scale_by_ratio * (double) promo_heap_delta);
if (PrintAdaptiveSizePolicy && Verbose) { log_trace(gc, ergo)("Scaled tenured increment: " SIZE_FORMAT " by %f down to " SIZE_FORMAT,
gclog_or_tty->print_cr( promo_heap_delta, scale_by_ratio, scaled_promo_heap_delta);
"Scaled tenured increment: " SIZE_FORMAT " by %f down to "
SIZE_FORMAT,
promo_heap_delta, scale_by_ratio, scaled_promo_heap_delta);
}
} else if (major_gc_cost() >= 0.0) { } else if (major_gc_cost() >= 0.0) {
// Scaling is not going to work. If the major gc time is the // Scaling is not going to work. If the major gc time is the
// larger, give it a full increment. // larger, give it a full increment.
@ -839,13 +763,10 @@ void PSAdaptiveSizePolicy::adjust_promo_for_throughput(bool is_full_gc,
_old_gen_change_for_major_throughput++; _old_gen_change_for_major_throughput++;
} }
if (PrintAdaptiveSizePolicy && Verbose) { log_trace(gc, ergo)("Adjusting tenured gen for throughput (avg %f goal %f). desired_promo_size " SIZE_FORMAT " promo_delta " SIZE_FORMAT ,
gclog_or_tty->print_cr( mutator_cost(),
"adjusting tenured gen for throughput (avg %f goal %f). " _throughput_goal,
"desired_promo_size " SIZE_FORMAT " promo_delta " SIZE_FORMAT , *desired_promo_size_ptr, scaled_promo_heap_delta);
mutator_cost(), _throughput_goal,
*desired_promo_size_ptr, scaled_promo_heap_delta);
}
} }
} }
@ -860,13 +781,8 @@ void PSAdaptiveSizePolicy::adjust_eden_for_throughput(bool is_full_gc,
return; return;
} }
if (PrintAdaptiveSizePolicy && Verbose) { log_trace(gc, ergo)("PSAdaptiveSizePolicy::adjust_eden_for_throughput(is_full: %d, cur_eden: " SIZE_FORMAT "): mutator_cost %f major_gc_cost %f minor_gc_cost %f",
gclog_or_tty->print("\nPSAdaptiveSizePolicy::adjust_eden_for_throughput(" is_full_gc, *desired_eden_size_ptr, mutator_cost(), major_gc_cost(), minor_gc_cost());
"is_full: %d, cur_eden: " SIZE_FORMAT "): ",
is_full_gc, *desired_eden_size_ptr);
gclog_or_tty->print_cr("mutator_cost %f major_gc_cost %f "
"minor_gc_cost %f", mutator_cost(), major_gc_cost(), minor_gc_cost());
}
// Young generation // Young generation
size_t scaled_eden_heap_delta = 0; size_t scaled_eden_heap_delta = 0;
@ -878,12 +794,8 @@ void PSAdaptiveSizePolicy::adjust_eden_for_throughput(bool is_full_gc,
assert(scale_by_ratio <= 1.0 && scale_by_ratio >= 0.0, "Scaling is wrong"); assert(scale_by_ratio <= 1.0 && scale_by_ratio >= 0.0, "Scaling is wrong");
scaled_eden_heap_delta = scaled_eden_heap_delta =
(size_t) (scale_by_ratio * (double) eden_heap_delta); (size_t) (scale_by_ratio * (double) eden_heap_delta);
if (PrintAdaptiveSizePolicy && Verbose) { log_trace(gc, ergo)("Scaled eden increment: " SIZE_FORMAT " by %f down to " SIZE_FORMAT,
gclog_or_tty->print_cr( eden_heap_delta, scale_by_ratio, scaled_eden_heap_delta);
"Scaled eden increment: " SIZE_FORMAT " by %f down to "
SIZE_FORMAT,
eden_heap_delta, scale_by_ratio, scaled_eden_heap_delta);
}
} else if (minor_gc_cost() >= 0.0) { } else if (minor_gc_cost() >= 0.0) {
// Scaling is not going to work. If the minor gc time is the // Scaling is not going to work. If the minor gc time is the
// larger, give it a full increment. // larger, give it a full increment.
@ -936,13 +848,8 @@ void PSAdaptiveSizePolicy::adjust_eden_for_throughput(bool is_full_gc,
_young_gen_change_for_minor_throughput++; _young_gen_change_for_minor_throughput++;
} }
if (PrintAdaptiveSizePolicy && Verbose) { log_trace(gc, ergo)("Adjusting eden for throughput (avg %f goal %f). desired_eden_size " SIZE_FORMAT " eden delta " SIZE_FORMAT,
gclog_or_tty->print_cr( mutator_cost(), _throughput_goal, *desired_eden_size_ptr, scaled_eden_heap_delta);
"adjusting eden for throughput (avg %f goal %f). desired_eden_size "
SIZE_FORMAT " eden delta " SIZE_FORMAT "\n",
mutator_cost(), _throughput_goal,
*desired_eden_size_ptr, scaled_eden_heap_delta);
}
} }
size_t PSAdaptiveSizePolicy::adjust_promo_for_footprint( size_t PSAdaptiveSizePolicy::adjust_promo_for_footprint(
@ -955,15 +862,13 @@ size_t PSAdaptiveSizePolicy::adjust_promo_for_footprint(
size_t reduced_size = desired_promo_size - change; size_t reduced_size = desired_promo_size - change;
if (PrintAdaptiveSizePolicy && Verbose) { log_trace(gc, ergo)(
gclog_or_tty->print_cr( "AdaptiveSizePolicy::adjust_promo_for_footprint "
"AdaptiveSizePolicy::adjust_promo_for_footprint " "adjusting tenured gen for footprint. "
"adjusting tenured gen for footprint. " "starting promo size " SIZE_FORMAT
"starting promo size " SIZE_FORMAT " reduced promo size " SIZE_FORMAT
" reduced promo size " SIZE_FORMAT " promo delta " SIZE_FORMAT,
" promo delta " SIZE_FORMAT, desired_promo_size, reduced_size, change );
desired_promo_size, reduced_size, change );
}
assert(reduced_size <= desired_promo_size, "Inconsistent result"); assert(reduced_size <= desired_promo_size, "Inconsistent result");
return reduced_size; return reduced_size;
@ -979,15 +884,13 @@ size_t PSAdaptiveSizePolicy::adjust_eden_for_footprint(
size_t reduced_size = desired_eden_size - change; size_t reduced_size = desired_eden_size - change;
if (PrintAdaptiveSizePolicy && Verbose) { log_trace(gc, ergo)(
gclog_or_tty->print_cr( "AdaptiveSizePolicy::adjust_eden_for_footprint "
"AdaptiveSizePolicy::adjust_eden_for_footprint " "adjusting eden for footprint. "
"adjusting eden for footprint. " " starting eden size " SIZE_FORMAT
" starting eden size " SIZE_FORMAT " reduced eden size " SIZE_FORMAT
" reduced eden size " SIZE_FORMAT " eden delta " SIZE_FORMAT,
" eden delta " SIZE_FORMAT, desired_eden_size, reduced_size, change);
desired_eden_size, reduced_size, change);
}
assert(reduced_size <= desired_eden_size, "Inconsistent result"); assert(reduced_size <= desired_eden_size, "Inconsistent result");
return reduced_size; return reduced_size;
@ -1187,33 +1090,14 @@ uint PSAdaptiveSizePolicy::compute_survivor_space_size_and_threshold(
// the amount of old gen free space is less than what we expect to // the amount of old gen free space is less than what we expect to
// promote). // promote).
if (PrintAdaptiveSizePolicy) { log_trace(gc, ergo)("avg_survived: %f avg_deviation: %f", _avg_survived->average(), _avg_survived->deviation());
// A little more detail if Verbose is on log_debug(gc, ergo)("avg_survived_padded_avg: %f", _avg_survived->padded_average());
if (Verbose) {
gclog_or_tty->print( " avg_survived: %f"
" avg_deviation: %f",
_avg_survived->average(),
_avg_survived->deviation());
}
gclog_or_tty->print( " avg_survived_padded_avg: %f", log_trace(gc, ergo)("avg_promoted_avg: %f avg_promoted_dev: %f", avg_promoted()->average(), avg_promoted()->deviation());
_avg_survived->padded_average()); log_debug(gc, ergo)("avg_promoted_padded_avg: %f avg_pretenured_padded_avg: %f tenuring_thresh: %d target_size: " SIZE_FORMAT,
avg_promoted()->padded_average(),
if (Verbose) { _avg_pretenured->padded_average(),
gclog_or_tty->print( " avg_promoted_avg: %f" tenuring_threshold, target_size);
" avg_promoted_dev: %f",
avg_promoted()->average(),
avg_promoted()->deviation());
}
gclog_or_tty->print_cr( " avg_promoted_padded_avg: %f"
" avg_pretenured_padded_avg: %f"
" tenuring_thresh: %d"
" target_size: " SIZE_FORMAT,
avg_promoted()->padded_average(),
_avg_pretenured->padded_average(),
tenuring_threshold, target_size);
}
set_survivor_size(target_size); set_survivor_size(target_size);
@ -1233,24 +1117,22 @@ void PSAdaptiveSizePolicy::update_averages(bool is_survivor_overflow,
} }
avg_promoted()->sample(promoted); avg_promoted()->sample(promoted);
if (PrintAdaptiveSizePolicy) { log_trace(gc, ergo)("AdaptiveSizePolicy::update_averages: survived: " SIZE_FORMAT " promoted: " SIZE_FORMAT " overflow: %s",
gclog_or_tty->print_cr( survived, promoted, is_survivor_overflow ? "true" : "false");
"AdaptiveSizePolicy::update_averages:"
" survived: " SIZE_FORMAT
" promoted: " SIZE_FORMAT
" overflow: %s",
survived, promoted, is_survivor_overflow ? "true" : "false");
}
} }
bool PSAdaptiveSizePolicy::print_adaptive_size_policy_on(outputStream* st) bool PSAdaptiveSizePolicy::print() const {
const {
if (!UseAdaptiveSizePolicy) return false; if (!UseAdaptiveSizePolicy) {
return false;
}
return AdaptiveSizePolicy::print_adaptive_size_policy_on( if (AdaptiveSizePolicy::print()) {
st, AdaptiveSizePolicy::print_tenuring_threshold(PSScavenge::tenuring_threshold());
PSScavenge::tenuring_threshold()); return true;
}
return false;
} }
#ifndef PRODUCT #ifndef PRODUCT

View file

@ -395,7 +395,7 @@ class PSAdaptiveSizePolicy : public AdaptiveSizePolicy {
size_t promoted); size_t promoted);
// Printing support // Printing support
virtual bool print_adaptive_size_policy_on(outputStream* st) const; virtual bool print() const;
// Decay the supplemental growth additive. // Decay the supplemental growth additive.
void decay_supplemental_growth(bool is_full_gc); void decay_supplemental_growth(bool is_full_gc);

View file

@ -32,6 +32,7 @@
#include "gc/parallel/psOldGen.hpp" #include "gc/parallel/psOldGen.hpp"
#include "gc/parallel/psParallelCompact.inline.hpp" #include "gc/parallel/psParallelCompact.inline.hpp"
#include "gc/shared/taskqueue.inline.hpp" #include "gc/shared/taskqueue.inline.hpp"
#include "logging/log.hpp"
#include "memory/iterator.inline.hpp" #include "memory/iterator.inline.hpp"
#include "oops/instanceKlass.inline.hpp" #include "oops/instanceKlass.inline.hpp"
#include "oops/instanceMirrorKlass.inline.hpp" #include "oops/instanceMirrorKlass.inline.hpp"
@ -229,30 +230,18 @@ template <class T>
static void oop_pc_follow_contents_specialized(InstanceRefKlass* klass, oop obj, ParCompactionManager* cm) { static void oop_pc_follow_contents_specialized(InstanceRefKlass* klass, oop obj, ParCompactionManager* cm) {
T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj); T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
T heap_oop = oopDesc::load_heap_oop(referent_addr); T heap_oop = oopDesc::load_heap_oop(referent_addr);
debug_only( log_develop_trace(gc, ref)("InstanceRefKlass::oop_pc_follow_contents " PTR_FORMAT, p2i(obj));
if(TraceReferenceGC && PrintGCDetails) {
gclog_or_tty->print_cr("InstanceRefKlass::oop_pc_follow_contents " PTR_FORMAT, p2i(obj));
}
)
if (!oopDesc::is_null(heap_oop)) { if (!oopDesc::is_null(heap_oop)) {
oop referent = oopDesc::decode_heap_oop_not_null(heap_oop); oop referent = oopDesc::decode_heap_oop_not_null(heap_oop);
if (PSParallelCompact::mark_bitmap()->is_unmarked(referent) && if (PSParallelCompact::mark_bitmap()->is_unmarked(referent) &&
PSParallelCompact::ref_processor()->discover_reference(obj, klass->reference_type())) { PSParallelCompact::ref_processor()->discover_reference(obj, klass->reference_type())) {
// reference already enqueued, referent will be traversed later // reference already enqueued, referent will be traversed later
klass->InstanceKlass::oop_pc_follow_contents(obj, cm); klass->InstanceKlass::oop_pc_follow_contents(obj, cm);
debug_only( log_develop_trace(gc, ref)(" Non NULL enqueued " PTR_FORMAT, p2i(obj));
if(TraceReferenceGC && PrintGCDetails) {
gclog_or_tty->print_cr(" Non NULL enqueued " PTR_FORMAT, p2i(obj));
}
)
return; return;
} else { } else {
// treat referent as normal oop // treat referent as normal oop
debug_only( log_develop_trace(gc, ref)(" Non NULL normal " PTR_FORMAT, p2i(obj));
if(TraceReferenceGC && PrintGCDetails) {
gclog_or_tty->print_cr(" Non NULL normal " PTR_FORMAT, p2i(obj));
}
)
cm->mark_and_push(referent_addr); cm->mark_and_push(referent_addr);
} }
} }
@ -262,12 +251,7 @@ static void oop_pc_follow_contents_specialized(InstanceRefKlass* klass, oop obj,
T next_oop = oopDesc::load_heap_oop(next_addr); T next_oop = oopDesc::load_heap_oop(next_addr);
if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active" if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active"
T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj); T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
debug_only( log_develop_trace(gc, ref)(" Process discovered as normal " PTR_FORMAT, p2i(discovered_addr));
if(TraceReferenceGC && PrintGCDetails) {
gclog_or_tty->print_cr(" Process discovered as normal "
PTR_FORMAT, p2i(discovered_addr));
}
)
cm->mark_and_push(discovered_addr); cm->mark_and_push(discovered_addr);
} }
cm->mark_and_push(next_addr); cm->mark_and_push(next_addr);

View file

@ -41,11 +41,12 @@
#include "gc/shared/gcLocker.inline.hpp" #include "gc/shared/gcLocker.inline.hpp"
#include "gc/shared/gcTimer.hpp" #include "gc/shared/gcTimer.hpp"
#include "gc/shared/gcTrace.hpp" #include "gc/shared/gcTrace.hpp"
#include "gc/shared/gcTraceTime.hpp" #include "gc/shared/gcTraceTime.inline.hpp"
#include "gc/shared/isGCActiveMark.hpp" #include "gc/shared/isGCActiveMark.hpp"
#include "gc/shared/referencePolicy.hpp" #include "gc/shared/referencePolicy.hpp"
#include "gc/shared/referenceProcessor.hpp" #include "gc/shared/referenceProcessor.hpp"
#include "gc/shared/spaceDecorator.hpp" #include "gc/shared/spaceDecorator.hpp"
#include "logging/log.hpp"
#include "oops/oop.inline.hpp" #include "oops/oop.inline.hpp"
#include "runtime/biasedLocking.hpp" #include "runtime/biasedLocking.hpp"
#include "runtime/fprofiler.hpp" #include "runtime/fprofiler.hpp"
@ -137,8 +138,6 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
// We need to track unique mark sweep invocations as well. // We need to track unique mark sweep invocations as well.
_total_invocations++; _total_invocations++;
AdaptiveSizePolicyOutput(size_policy, heap->total_collections());
heap->print_heap_before_gc(); heap->print_heap_before_gc();
heap->trace_heap_before_gc(_gc_tracer); heap->trace_heap_before_gc(_gc_tracer);
@ -148,7 +147,7 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
if (VerifyBeforeGC && heap->total_collections() >= VerifyGCStartAt) { if (VerifyBeforeGC && heap->total_collections() >= VerifyGCStartAt) {
HandleMark hm; // Discard invalid handles created during verification HandleMark hm; // Discard invalid handles created during verification
Universe::verify(" VerifyBeforeGC:"); Universe::verify("Before GC");
} }
// Verify object start arrays // Verify object start arrays
@ -167,8 +166,8 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
{ {
HandleMark hm; HandleMark hm;
TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); GCTraceCPUTime tcpu;
GCTraceTime t1(GCCauseString("Full GC", gc_cause), PrintGC, !PrintGCDetails, NULL); GCTraceTime(Info, gc) t("Pause Full", NULL, gc_cause, true);
TraceCollectorStats tcs(counters()); TraceCollectorStats tcs(counters());
TraceMemoryManagerStats tms(true /* Full GC */,gc_cause); TraceMemoryManagerStats tms(true /* Full GC */,gc_cause);
@ -180,13 +179,9 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
CodeCache::gc_prologue(); CodeCache::gc_prologue();
BiasedLocking::preserve_marks(); BiasedLocking::preserve_marks();
// Capture heap size before collection for printing.
size_t prev_used = heap->used();
// Capture metadata size before collection for sizing. // Capture metadata size before collection for sizing.
size_t metadata_prev_used = MetaspaceAux::used_bytes(); size_t metadata_prev_used = MetaspaceAux::used_bytes();
// For PrintGCDetails
size_t old_gen_prev_used = old_gen->used_in_bytes(); size_t old_gen_prev_used = old_gen->used_in_bytes();
size_t young_gen_prev_used = young_gen->used_in_bytes(); size_t young_gen_prev_used = young_gen->used_in_bytes();
@ -266,17 +261,9 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
if (UseAdaptiveSizePolicy) { if (UseAdaptiveSizePolicy) {
if (PrintAdaptiveSizePolicy) { log_debug(gc, ergo)("AdaptiveSizeStart: collection: %d ", heap->total_collections());
gclog_or_tty->print("AdaptiveSizeStart: "); log_trace(gc, ergo)("old_gen_capacity: " SIZE_FORMAT " young_gen_capacity: " SIZE_FORMAT,
gclog_or_tty->stamp(); old_gen->capacity_in_bytes(), young_gen->capacity_in_bytes());
gclog_or_tty->print_cr(" collection: %d ",
heap->total_collections());
if (Verbose) {
gclog_or_tty->print("old_gen_capacity: " SIZE_FORMAT
" young_gen_capacity: " SIZE_FORMAT,
old_gen->capacity_in_bytes(), young_gen->capacity_in_bytes());
}
}
// Don't check if the size_policy is ready here. Let // Don't check if the size_policy is ready here. Let
// the size_policy check that internally. // the size_policy check that internally.
@ -333,10 +320,7 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
heap->resize_young_gen(size_policy->calculated_eden_size_in_bytes(), heap->resize_young_gen(size_policy->calculated_eden_size_in_bytes(),
size_policy->calculated_survivor_size_in_bytes()); size_policy->calculated_survivor_size_in_bytes());
} }
if (PrintAdaptiveSizePolicy) { log_debug(gc, ergo)("AdaptiveSizeStop: collection: %d ", heap->total_collections());
gclog_or_tty->print_cr("AdaptiveSizeStop: collection: %d ",
heap->total_collections());
}
} }
if (UsePerfData) { if (UsePerfData) {
@ -354,18 +338,9 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
if (TraceOldGenTime) accumulated_time()->stop(); if (TraceOldGenTime) accumulated_time()->stop();
if (PrintGC) { young_gen->print_used_change(young_gen_prev_used);
if (PrintGCDetails) { old_gen->print_used_change(old_gen_prev_used);
// Don't print a GC timestamp here. This is after the GC so MetaspaceAux::print_metaspace_change(metadata_prev_used);
// would be confusing.
young_gen->print_used_change(young_gen_prev_used);
old_gen->print_used_change(old_gen_prev_used);
}
heap->print_heap_change(prev_used);
if (PrintGCDetails) {
MetaspaceAux::print_metaspace_change(metadata_prev_used);
}
}
// Track memory usage and detect low memory // Track memory usage and detect low memory
MemoryService::track_memory_usage(); MemoryService::track_memory_usage();
@ -374,7 +349,7 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
if (VerifyAfterGC && heap->total_collections() >= VerifyGCStartAt) { if (VerifyAfterGC && heap->total_collections() >= VerifyGCStartAt) {
HandleMark hm; // Discard invalid handles created during verification HandleMark hm; // Discard invalid handles created during verification
Universe::verify(" VerifyAfterGC:"); Universe::verify("After GC");
} }
// Re-verify object start arrays // Re-verify object start arrays
@ -398,6 +373,8 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
ParallelTaskTerminator::print_termination_counts(); ParallelTaskTerminator::print_termination_counts();
#endif #endif
AdaptiveSizePolicyOutput::print(size_policy, heap->total_collections());
_gc_timer->register_gc_end(); _gc_timer->register_gc_end();
_gc_tracer->report_gc_end(_gc_timer->gc_end(), _gc_timer->time_partitions()); _gc_tracer->report_gc_end(_gc_timer->gc_end(), _gc_timer->time_partitions());
@ -443,8 +420,7 @@ bool PSMarkSweep::absorb_live_data_from_eden(PSAdaptiveSizePolicy* size_policy,
return false; // Respect young gen minimum size. return false; // Respect young gen minimum size.
} }
if (TraceAdaptiveGCBoundary && Verbose) { log_trace(heap, ergo)(" absorbing " SIZE_FORMAT "K: "
gclog_or_tty->print(" absorbing " SIZE_FORMAT "K: "
"eden " SIZE_FORMAT "K->" SIZE_FORMAT "K " "eden " SIZE_FORMAT "K->" SIZE_FORMAT "K "
"from " SIZE_FORMAT "K, to " SIZE_FORMAT "K " "from " SIZE_FORMAT "K, to " SIZE_FORMAT "K "
"young_gen " SIZE_FORMAT "K->" SIZE_FORMAT "K ", "young_gen " SIZE_FORMAT "K->" SIZE_FORMAT "K ",
@ -453,7 +429,6 @@ bool PSMarkSweep::absorb_live_data_from_eden(PSAdaptiveSizePolicy* size_policy,
young_gen->from_space()->used_in_bytes() / K, young_gen->from_space()->used_in_bytes() / K,
young_gen->to_space()->used_in_bytes() / K, young_gen->to_space()->used_in_bytes() / K,
young_gen->capacity_in_bytes() / K, new_young_size / K); young_gen->capacity_in_bytes() / K, new_young_size / K);
}
// Fill the unused part of the old gen. // Fill the unused part of the old gen.
MutableSpace* const old_space = old_gen->object_space(); MutableSpace* const old_space = old_gen->object_space();
@ -517,7 +492,7 @@ void PSMarkSweep::deallocate_stacks() {
void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) { void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
// Recursively traverse all live objects and mark them // Recursively traverse all live objects and mark them
GCTraceTime tm("phase 1", PrintGCDetails && Verbose, true, _gc_timer); GCTraceTime(Trace, gc) tm("Phase 1: Mark live objects", _gc_timer);
ParallelScavengeHeap* heap = ParallelScavengeHeap::heap(); ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
@ -576,7 +551,7 @@ void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
void PSMarkSweep::mark_sweep_phase2() { void PSMarkSweep::mark_sweep_phase2() {
GCTraceTime tm("phase 2", PrintGCDetails && Verbose, true, _gc_timer); GCTraceTime(Trace, gc) tm("Phase 2: Compute new object addresses", _gc_timer);
// Now all live objects are marked, compute the new object addresses. // Now all live objects are marked, compute the new object addresses.
@ -603,7 +578,7 @@ static PSAlwaysTrueClosure always_true;
void PSMarkSweep::mark_sweep_phase3() { void PSMarkSweep::mark_sweep_phase3() {
// Adjust the pointers to reflect the new locations // Adjust the pointers to reflect the new locations
GCTraceTime tm("phase 3", PrintGCDetails && Verbose, true, _gc_timer); GCTraceTime(Trace, gc) tm("Phase 3: Adjust pointers", _gc_timer);
ParallelScavengeHeap* heap = ParallelScavengeHeap::heap(); ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
PSYoungGen* young_gen = heap->young_gen(); PSYoungGen* young_gen = heap->young_gen();
@ -643,7 +618,7 @@ void PSMarkSweep::mark_sweep_phase3() {
void PSMarkSweep::mark_sweep_phase4() { void PSMarkSweep::mark_sweep_phase4() {
EventMark m("4 compact heap"); EventMark m("4 compact heap");
GCTraceTime tm("phase 4", PrintGCDetails && Verbose, true, _gc_timer); GCTraceTime(Trace, gc) tm("Phase 4: Move objects", _gc_timer);
// All pointers are now adjusted, move objects accordingly // All pointers are now adjusted, move objects accordingly

View file

@ -30,6 +30,7 @@
#include "gc/shared/cardTableModRefBS.hpp" #include "gc/shared/cardTableModRefBS.hpp"
#include "gc/shared/gcLocker.inline.hpp" #include "gc/shared/gcLocker.inline.hpp"
#include "gc/shared/spaceDecorator.hpp" #include "gc/shared/spaceDecorator.hpp"
#include "logging/log.hpp"
#include "oops/oop.inline.hpp" #include "oops/oop.inline.hpp"
#include "runtime/java.hpp" #include "runtime/java.hpp"
@ -256,10 +257,8 @@ void PSOldGen::expand(size_t bytes) {
success = expand_to_reserved(); success = expand_to_reserved();
} }
if (PrintGC && Verbose) { if (success && GC_locker::is_active_and_needs_gc()) {
if (success && GC_locker::is_active_and_needs_gc()) { log_debug(gc)("Garbage collection disabled, expanded heap instead");
gclog_or_tty->print_cr("Garbage collection disabled, expanded heap instead");
}
} }
} }
@ -291,13 +290,11 @@ bool PSOldGen::expand_by(size_t bytes) {
} }
} }
if (result && Verbose && PrintGC) { if (result) {
size_t new_mem_size = virtual_space()->committed_size(); size_t new_mem_size = virtual_space()->committed_size();
size_t old_mem_size = new_mem_size - bytes; size_t old_mem_size = new_mem_size - bytes;
gclog_or_tty->print_cr("Expanding %s from " SIZE_FORMAT "K by " log_debug(gc)("Expanding %s from " SIZE_FORMAT "K by " SIZE_FORMAT "K to " SIZE_FORMAT "K",
SIZE_FORMAT "K to " name(), old_mem_size/K, bytes/K, new_mem_size/K);
SIZE_FORMAT "K",
name(), old_mem_size/K, bytes/K, new_mem_size/K);
} }
return result; return result;
@ -326,14 +323,10 @@ void PSOldGen::shrink(size_t bytes) {
virtual_space()->shrink_by(bytes); virtual_space()->shrink_by(bytes);
post_resize(); post_resize();
if (Verbose && PrintGC) { size_t new_mem_size = virtual_space()->committed_size();
size_t new_mem_size = virtual_space()->committed_size(); size_t old_mem_size = new_mem_size + bytes;
size_t old_mem_size = new_mem_size + bytes; log_debug(gc)("Shrinking %s from " SIZE_FORMAT "K by " SIZE_FORMAT "K to " SIZE_FORMAT "K",
gclog_or_tty->print_cr("Shrinking %s from " SIZE_FORMAT "K by " name(), old_mem_size/K, bytes/K, new_mem_size/K);
SIZE_FORMAT "K to "
SIZE_FORMAT "K",
name(), old_mem_size/K, bytes/K, new_mem_size/K);
}
} }
} }
@ -353,14 +346,12 @@ void PSOldGen::resize(size_t desired_free_space) {
const size_t current_size = capacity_in_bytes(); const size_t current_size = capacity_in_bytes();
if (PrintAdaptiveSizePolicy && Verbose) { log_trace(gc, ergo)("AdaptiveSizePolicy::old generation size: "
gclog_or_tty->print_cr("AdaptiveSizePolicy::old generation size: " "desired free: " SIZE_FORMAT " used: " SIZE_FORMAT
"desired free: " SIZE_FORMAT " used: " SIZE_FORMAT " new size: " SIZE_FORMAT " current size " SIZE_FORMAT
" new size: " SIZE_FORMAT " current size " SIZE_FORMAT " gen limits: " SIZE_FORMAT " / " SIZE_FORMAT,
" gen limits: " SIZE_FORMAT " / " SIZE_FORMAT, desired_free_space, used_in_bytes(), new_size, current_size,
desired_free_space, used_in_bytes(), new_size, current_size, gen_size_limit(), min_gen_size());
gen_size_limit(), min_gen_size());
}
if (new_size == current_size) { if (new_size == current_size) {
// No change requested // No change requested
@ -376,14 +367,10 @@ void PSOldGen::resize(size_t desired_free_space) {
shrink(change_bytes); shrink(change_bytes);
} }
if (PrintAdaptiveSizePolicy) { log_trace(gc, ergo)("AdaptiveSizePolicy::old generation size: collection: %d (" SIZE_FORMAT ") -> (" SIZE_FORMAT ") ",
ParallelScavengeHeap* heap = ParallelScavengeHeap::heap(); ParallelScavengeHeap::heap()->total_collections(),
gclog_or_tty->print_cr("AdaptiveSizePolicy::old generation size: " size_before,
"collection: %d " virtual_space()->committed_size());
"(" SIZE_FORMAT ") -> (" SIZE_FORMAT ") ",
heap->total_collections(),
size_before, virtual_space()->committed_size());
}
} }
// NOTE! We need to be careful about resizing. During a GC, multiple // NOTE! We need to be careful about resizing. During a GC, multiple
@ -430,13 +417,8 @@ size_t PSOldGen::available_for_contraction() {
void PSOldGen::print() const { print_on(tty);} void PSOldGen::print() const { print_on(tty);}
void PSOldGen::print_on(outputStream* st) const { void PSOldGen::print_on(outputStream* st) const {
st->print(" %-15s", name()); st->print(" %-15s", name());
if (PrintGCDetails && Verbose) { st->print(" total " SIZE_FORMAT "K, used " SIZE_FORMAT "K",
st->print(" total " SIZE_FORMAT ", used " SIZE_FORMAT, capacity_in_bytes()/K, used_in_bytes()/K);
capacity_in_bytes(), used_in_bytes());
} else {
st->print(" total " SIZE_FORMAT "K, used " SIZE_FORMAT "K",
capacity_in_bytes()/K, used_in_bytes()/K);
}
st->print_cr(" [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " INTPTR_FORMAT ")", st->print_cr(" [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " INTPTR_FORMAT ")",
p2i(virtual_space()->low_boundary()), p2i(virtual_space()->low_boundary()),
p2i(virtual_space()->high()), p2i(virtual_space()->high()),
@ -446,13 +428,8 @@ void PSOldGen::print_on(outputStream* st) const {
} }
void PSOldGen::print_used_change(size_t prev_used) const { void PSOldGen::print_used_change(size_t prev_used) const {
gclog_or_tty->print(" [%s:", name()); log_info(gc, heap)("%s: " SIZE_FORMAT "K->" SIZE_FORMAT "K(" SIZE_FORMAT "K)",
gclog_or_tty->print(" " SIZE_FORMAT "K" name(), prev_used / K, used_in_bytes() / K, capacity_in_bytes() / K);
"->" SIZE_FORMAT "K"
"(" SIZE_FORMAT "K)",
prev_used / K, used_in_bytes() / K,
capacity_in_bytes() / K);
gclog_or_tty->print("]");
} }
void PSOldGen::update_counters() { void PSOldGen::update_counters() {

View file

@ -45,11 +45,12 @@
#include "gc/shared/gcLocker.inline.hpp" #include "gc/shared/gcLocker.inline.hpp"
#include "gc/shared/gcTimer.hpp" #include "gc/shared/gcTimer.hpp"
#include "gc/shared/gcTrace.hpp" #include "gc/shared/gcTrace.hpp"
#include "gc/shared/gcTraceTime.hpp" #include "gc/shared/gcTraceTime.inline.hpp"
#include "gc/shared/isGCActiveMark.hpp" #include "gc/shared/isGCActiveMark.hpp"
#include "gc/shared/referencePolicy.hpp" #include "gc/shared/referencePolicy.hpp"
#include "gc/shared/referenceProcessor.hpp" #include "gc/shared/referenceProcessor.hpp"
#include "gc/shared/spaceDecorator.hpp" #include "gc/shared/spaceDecorator.hpp"
#include "logging/log.hpp"
#include "oops/instanceKlass.inline.hpp" #include "oops/instanceKlass.inline.hpp"
#include "oops/instanceMirrorKlass.inline.hpp" #include "oops/instanceMirrorKlass.inline.hpp"
#include "oops/methodData.hpp" #include "oops/methodData.hpp"
@ -107,7 +108,6 @@ const ParallelCompactData::RegionData::region_sz_t
ParallelCompactData::RegionData::dc_completed = 0xcU << dc_shift; ParallelCompactData::RegionData::dc_completed = 0xcU << dc_shift;
SpaceInfo PSParallelCompact::_space_info[PSParallelCompact::last_space_id]; SpaceInfo PSParallelCompact::_space_info[PSParallelCompact::last_space_id];
bool PSParallelCompact::_print_phases = false;
ReferenceProcessor* PSParallelCompact::_ref_processor = NULL; ReferenceProcessor* PSParallelCompact::_ref_processor = NULL;
@ -194,21 +194,26 @@ const char* PSParallelCompact::space_names[] = {
"old ", "eden", "from", "to " "old ", "eden", "from", "to "
}; };
void PSParallelCompact::print_region_ranges() void PSParallelCompact::print_region_ranges() {
{ if (!develop_log_is_enabled(Trace, gc, compaction, phases)) {
tty->print_cr("space bottom top end new_top"); return;
tty->print_cr("------ ---------- ---------- ---------- ----------"); }
LogHandle(gc, compaction, phases) log;
ResourceMark rm;
Universe::print_on(log.trace_stream());
log.trace("space bottom top end new_top");
log.trace("------ ---------- ---------- ---------- ----------");
for (unsigned int id = 0; id < last_space_id; ++id) { for (unsigned int id = 0; id < last_space_id; ++id) {
const MutableSpace* space = _space_info[id].space(); const MutableSpace* space = _space_info[id].space();
tty->print_cr("%u %s " log.trace("%u %s "
SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10) " "
SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10) " ", SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10) " ",
id, space_names[id], id, space_names[id],
summary_data().addr_to_region_idx(space->bottom()), summary_data().addr_to_region_idx(space->bottom()),
summary_data().addr_to_region_idx(space->top()), summary_data().addr_to_region_idx(space->top()),
summary_data().addr_to_region_idx(space->end()), summary_data().addr_to_region_idx(space->end()),
summary_data().addr_to_region_idx(_space_info[id].new_top())); summary_data().addr_to_region_idx(_space_info[id].new_top()));
} }
} }
@ -220,13 +225,14 @@ print_generic_summary_region(size_t i, const ParallelCompactData::RegionData* c)
ParallelCompactData& sd = PSParallelCompact::summary_data(); ParallelCompactData& sd = PSParallelCompact::summary_data();
size_t dci = c->destination() ? sd.addr_to_region_idx(c->destination()) : 0; size_t dci = c->destination() ? sd.addr_to_region_idx(c->destination()) : 0;
tty->print_cr(REGION_IDX_FORMAT " " PTR_FORMAT " " log_develop_trace(gc, compaction, phases)(
REGION_IDX_FORMAT " " PTR_FORMAT " " REGION_IDX_FORMAT " " PTR_FORMAT " "
REGION_DATA_FORMAT " " REGION_DATA_FORMAT " " REGION_IDX_FORMAT " " PTR_FORMAT " "
REGION_DATA_FORMAT " " REGION_IDX_FORMAT " %d", REGION_DATA_FORMAT " " REGION_DATA_FORMAT " "
i, p2i(c->data_location()), dci, p2i(c->destination()), REGION_DATA_FORMAT " " REGION_IDX_FORMAT " %d",
c->partial_obj_size(), c->live_obj_size(), i, p2i(c->data_location()), dci, p2i(c->destination()),
c->data_size(), c->source_region(), c->destination_count()); c->partial_obj_size(), c->live_obj_size(),
c->data_size(), c->source_region(), c->destination_count());
#undef REGION_IDX_FORMAT #undef REGION_IDX_FORMAT
#undef REGION_DATA_FORMAT #undef REGION_DATA_FORMAT
@ -252,13 +258,17 @@ print_generic_summary_data(ParallelCompactData& summary_data,
++i; ++i;
} }
tty->print_cr("summary_data_bytes=" SIZE_FORMAT, total_words * HeapWordSize); log_develop_trace(gc, compaction, phases)("summary_data_bytes=" SIZE_FORMAT, total_words * HeapWordSize);
} }
void void
print_generic_summary_data(ParallelCompactData& summary_data, print_generic_summary_data(ParallelCompactData& summary_data,
SpaceInfo* space_info) SpaceInfo* space_info)
{ {
if (!develop_log_is_enabled(Trace, gc, compaction, phases)) {
return;
}
for (unsigned int id = 0; id < PSParallelCompact::last_space_id; ++id) { for (unsigned int id = 0; id < PSParallelCompact::last_space_id; ++id) {
const MutableSpace* space = space_info[id].space(); const MutableSpace* space = space_info[id].space();
print_generic_summary_data(summary_data, space->bottom(), print_generic_summary_data(summary_data, space->bottom(),
@ -266,20 +276,6 @@ print_generic_summary_data(ParallelCompactData& summary_data,
} }
} }
void
print_initial_summary_region(size_t i,
const ParallelCompactData::RegionData* c,
bool newline = true)
{
tty->print(SIZE_FORMAT_W(5) " " PTR_FORMAT " "
SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " "
SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " %d",
i, p2i(c->destination()),
c->partial_obj_size(), c->live_obj_size(),
c->data_size(), c->source_region(), c->destination_count());
if (newline) tty->cr();
}
void void
print_initial_summary_data(ParallelCompactData& summary_data, print_initial_summary_data(ParallelCompactData& summary_data,
const MutableSpace* space) { const MutableSpace* space) {
@ -299,7 +295,12 @@ print_initial_summary_data(ParallelCompactData& summary_data,
size_t full_region_count = 0; size_t full_region_count = 0;
size_t i = summary_data.addr_to_region_idx(space->bottom()); size_t i = summary_data.addr_to_region_idx(space->bottom());
while (i < end_region && summary_data.region(i)->data_size() == region_size) { while (i < end_region && summary_data.region(i)->data_size() == region_size) {
print_initial_summary_region(i, summary_data.region(i)); ParallelCompactData::RegionData* c = summary_data.region(i);
log_develop_trace(gc, compaction, phases)(
SIZE_FORMAT_W(5) " " PTR_FORMAT " " SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " %d",
i, p2i(c->destination()),
c->partial_obj_size(), c->live_obj_size(),
c->data_size(), c->source_region(), c->destination_count());
++full_region_count; ++full_region_count;
++i; ++i;
} }
@ -328,9 +329,15 @@ print_initial_summary_data(ParallelCompactData& summary_data,
max_live_to_right = live_to_right; max_live_to_right = live_to_right;
} }
print_initial_summary_region(i, c, false); ParallelCompactData::RegionData* c = summary_data.region(i);
tty->print_cr(" %12.10f " SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10), log_develop_trace(gc, compaction, phases)(
reclaimed_ratio, dead_to_right, live_to_right); SIZE_FORMAT_W(5) " " PTR_FORMAT " " SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " %d"
"%12.10f " SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10),
i, p2i(c->destination()),
c->partial_obj_size(), c->live_obj_size(),
c->data_size(), c->source_region(), c->destination_count(),
reclaimed_ratio, dead_to_right, live_to_right);
live_to_right -= c->data_size(); live_to_right -= c->data_size();
++i; ++i;
@ -338,18 +345,25 @@ print_initial_summary_data(ParallelCompactData& summary_data,
// Any remaining regions are empty. Print one more if there is one. // Any remaining regions are empty. Print one more if there is one.
if (i < end_region) { if (i < end_region) {
print_initial_summary_region(i, summary_data.region(i)); ParallelCompactData::RegionData* c = summary_data.region(i);
log_develop_trace(gc, compaction, phases)(
SIZE_FORMAT_W(5) " " PTR_FORMAT " " SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " %d",
i, p2i(c->destination()),
c->partial_obj_size(), c->live_obj_size(),
c->data_size(), c->source_region(), c->destination_count());
} }
tty->print_cr("max: " SIZE_FORMAT_W(4) " d2r=" SIZE_FORMAT_W(10) " " log_develop_trace(gc, compaction, phases)("max: " SIZE_FORMAT_W(4) " d2r=" SIZE_FORMAT_W(10) " l2r=" SIZE_FORMAT_W(10) " max_ratio=%14.12f",
"l2r=" SIZE_FORMAT_W(10) " max_ratio=%14.12f", max_reclaimed_ratio_region, max_dead_to_right, max_live_to_right, max_reclaimed_ratio);
max_reclaimed_ratio_region, max_dead_to_right,
max_live_to_right, max_reclaimed_ratio);
} }
void void
print_initial_summary_data(ParallelCompactData& summary_data, print_initial_summary_data(ParallelCompactData& summary_data,
SpaceInfo* space_info) { SpaceInfo* space_info) {
if (!develop_log_is_enabled(Trace, gc, compaction, phases)) {
return;
}
unsigned int id = PSParallelCompact::old_space_id; unsigned int id = PSParallelCompact::old_space_id;
const MutableSpace* space; const MutableSpace* space;
do { do {
@ -607,11 +621,7 @@ ParallelCompactData::summarize_split_space(size_t src_region,
sr->partial_obj_size())); sr->partial_obj_size()));
const size_t end_idx = addr_to_region_idx(target_end); const size_t end_idx = addr_to_region_idx(target_end);
if (TraceParallelOldGCSummaryPhase) { log_develop_trace(gc, compaction, phases)("split: clearing source_region field in [" SIZE_FORMAT ", " SIZE_FORMAT ")", beg_idx, end_idx);
gclog_or_tty->print_cr("split: clearing source_region field in ["
SIZE_FORMAT ", " SIZE_FORMAT ")",
beg_idx, end_idx);
}
for (size_t idx = beg_idx; idx < end_idx; ++idx) { for (size_t idx = beg_idx; idx < end_idx; ++idx) {
_region_data[idx].set_source_region(0); _region_data[idx].set_source_region(0);
} }
@ -631,27 +641,22 @@ ParallelCompactData::summarize_split_space(size_t src_region,
*target_next = split_destination + partial_obj_size; *target_next = split_destination + partial_obj_size;
HeapWord* const source_next = region_to_addr(split_region) + partial_obj_size; HeapWord* const source_next = region_to_addr(split_region) + partial_obj_size;
if (TraceParallelOldGCSummaryPhase) { if (develop_log_is_enabled(Trace, gc, compaction, phases)) {
const char * split_type = partial_obj_size == 0 ? "easy" : "hard"; const char * split_type = partial_obj_size == 0 ? "easy" : "hard";
gclog_or_tty->print_cr("%s split: src=" PTR_FORMAT " src_c=" SIZE_FORMAT log_develop_trace(gc, compaction, phases)("%s split: src=" PTR_FORMAT " src_c=" SIZE_FORMAT " pos=" SIZE_FORMAT,
" pos=" SIZE_FORMAT, split_type, p2i(source_next), split_region, partial_obj_size);
split_type, p2i(source_next), split_region, log_develop_trace(gc, compaction, phases)("%s split: dst=" PTR_FORMAT " dst_c=" SIZE_FORMAT " tn=" PTR_FORMAT,
partial_obj_size); split_type, p2i(split_destination),
gclog_or_tty->print_cr("%s split: dst=" PTR_FORMAT " dst_c=" SIZE_FORMAT addr_to_region_idx(split_destination),
" tn=" PTR_FORMAT, p2i(*target_next));
split_type, p2i(split_destination),
addr_to_region_idx(split_destination),
p2i(*target_next));
if (partial_obj_size != 0) { if (partial_obj_size != 0) {
HeapWord* const po_beg = split_info.destination(); HeapWord* const po_beg = split_info.destination();
HeapWord* const po_end = po_beg + split_info.partial_obj_size(); HeapWord* const po_end = po_beg + split_info.partial_obj_size();
gclog_or_tty->print_cr("%s split: " log_develop_trace(gc, compaction, phases)("%s split: po_beg=" PTR_FORMAT " " SIZE_FORMAT " po_end=" PTR_FORMAT " " SIZE_FORMAT,
"po_beg=" PTR_FORMAT " " SIZE_FORMAT " " split_type,
"po_end=" PTR_FORMAT " " SIZE_FORMAT, p2i(po_beg), addr_to_region_idx(po_beg),
split_type, p2i(po_end), addr_to_region_idx(po_end));
p2i(po_beg), addr_to_region_idx(po_beg),
p2i(po_end), addr_to_region_idx(po_end));
} }
} }
@ -664,13 +669,12 @@ bool ParallelCompactData::summarize(SplitInfo& split_info,
HeapWord* target_beg, HeapWord* target_end, HeapWord* target_beg, HeapWord* target_end,
HeapWord** target_next) HeapWord** target_next)
{ {
if (TraceParallelOldGCSummaryPhase) { HeapWord* const source_next_val = source_next == NULL ? NULL : *source_next;
HeapWord* const source_next_val = source_next == NULL ? NULL : *source_next; log_develop_trace(gc, compaction, phases)(
tty->print_cr("sb=" PTR_FORMAT " se=" PTR_FORMAT " sn=" PTR_FORMAT "sb=" PTR_FORMAT " se=" PTR_FORMAT " sn=" PTR_FORMAT
"tb=" PTR_FORMAT " te=" PTR_FORMAT " tn=" PTR_FORMAT, "tb=" PTR_FORMAT " te=" PTR_FORMAT " tn=" PTR_FORMAT,
p2i(source_beg), p2i(source_end), p2i(source_next_val), p2i(source_beg), p2i(source_end), p2i(source_next_val),
p2i(target_beg), p2i(target_end), p2i(*target_next)); p2i(target_beg), p2i(target_end), p2i(*target_next));
}
size_t cur_region = addr_to_region_idx(source_beg); size_t cur_region = addr_to_region_idx(source_beg);
const size_t end_region = addr_to_region_idx(region_align_up(source_end)); const size_t end_region = addr_to_region_idx(region_align_up(source_end));
@ -901,32 +905,6 @@ void PSParallelCompact::initialize_dead_wood_limiter()
_dwl_adjustment = normal_distribution(1.0); _dwl_adjustment = normal_distribution(1.0);
} }
// Simple class for storing info about the heap at the start of GC, to be used
// after GC for comparison/printing.
class PreGCValues {
public:
PreGCValues() { }
PreGCValues(ParallelScavengeHeap* heap) { fill(heap); }
void fill(ParallelScavengeHeap* heap) {
_heap_used = heap->used();
_young_gen_used = heap->young_gen()->used_in_bytes();
_old_gen_used = heap->old_gen()->used_in_bytes();
_metadata_used = MetaspaceAux::used_bytes();
};
size_t heap_used() const { return _heap_used; }
size_t young_gen_used() const { return _young_gen_used; }
size_t old_gen_used() const { return _old_gen_used; }
size_t metadata_used() const { return _metadata_used; }
private:
size_t _heap_used;
size_t _young_gen_used;
size_t _old_gen_used;
size_t _metadata_used;
};
void void
PSParallelCompact::clear_data_covering_space(SpaceId id) PSParallelCompact::clear_data_covering_space(SpaceId id)
{ {
@ -956,19 +934,17 @@ PSParallelCompact::clear_data_covering_space(SpaceId id)
DEBUG_ONLY(split_info.verify_clear();) DEBUG_ONLY(split_info.verify_clear();)
} }
void PSParallelCompact::pre_compact(PreGCValues* pre_gc_values) void PSParallelCompact::pre_compact()
{ {
// Update the from & to space pointers in space_info, since they are swapped // Update the from & to space pointers in space_info, since they are swapped
// at each young gen gc. Do the update unconditionally (even though a // at each young gen gc. Do the update unconditionally (even though a
// promotion failure does not swap spaces) because an unknown number of young // promotion failure does not swap spaces) because an unknown number of young
// collections will have swapped the spaces an unknown number of times. // collections will have swapped the spaces an unknown number of times.
GCTraceTime tm("pre compact", print_phases(), true, &_gc_timer); GCTraceTime(Trace, gc, phases) tm("Pre Compact", &_gc_timer);
ParallelScavengeHeap* heap = ParallelScavengeHeap::heap(); ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
_space_info[from_space_id].set_space(heap->young_gen()->from_space()); _space_info[from_space_id].set_space(heap->young_gen()->from_space());
_space_info[to_space_id].set_space(heap->young_gen()->to_space()); _space_info[to_space_id].set_space(heap->young_gen()->to_space());
pre_gc_values->fill(heap);
DEBUG_ONLY(add_obj_count = add_obj_size = 0;) DEBUG_ONLY(add_obj_count = add_obj_size = 0;)
DEBUG_ONLY(mark_bitmap_count = mark_bitmap_size = 0;) DEBUG_ONLY(mark_bitmap_count = mark_bitmap_size = 0;)
@ -987,7 +963,7 @@ void PSParallelCompact::pre_compact(PreGCValues* pre_gc_values)
if (VerifyBeforeGC && heap->total_collections() >= VerifyGCStartAt) { if (VerifyBeforeGC && heap->total_collections() >= VerifyGCStartAt) {
HandleMark hm; // Discard invalid handles created during verification HandleMark hm; // Discard invalid handles created during verification
Universe::verify(" VerifyBeforeGC:"); Universe::verify("Before GC");
} }
// Verify object start arrays // Verify object start arrays
@ -1005,7 +981,7 @@ void PSParallelCompact::pre_compact(PreGCValues* pre_gc_values)
void PSParallelCompact::post_compact() void PSParallelCompact::post_compact()
{ {
GCTraceTime tm("post compact", print_phases(), true, &_gc_timer); GCTraceTime(Trace, gc, phases) tm("Post Compact", &_gc_timer);
for (unsigned int id = old_space_id; id < last_space_id; ++id) { for (unsigned int id = old_space_id; id < last_space_id; ++id) {
// Clear the marking bitmap, summary data and split info. // Clear the marking bitmap, summary data and split info.
@ -1559,7 +1535,7 @@ PSParallelCompact::summarize_space(SpaceId id, bool maximum_compaction)
} }
} }
if (TraceParallelOldGCSummaryPhase) { if (develop_log_is_enabled(Trace, gc, compaction, phases)) {
const size_t region_size = ParallelCompactData::RegionSize; const size_t region_size = ParallelCompactData::RegionSize;
HeapWord* const dense_prefix_end = _space_info[id].dense_prefix(); HeapWord* const dense_prefix_end = _space_info[id].dense_prefix();
const size_t dp_region = _summary_data.addr_to_region_idx(dense_prefix_end); const size_t dp_region = _summary_data.addr_to_region_idx(dense_prefix_end);
@ -1567,12 +1543,13 @@ PSParallelCompact::summarize_space(SpaceId id, bool maximum_compaction)
HeapWord* const new_top = _space_info[id].new_top(); HeapWord* const new_top = _space_info[id].new_top();
const HeapWord* nt_aligned_up = _summary_data.region_align_up(new_top); const HeapWord* nt_aligned_up = _summary_data.region_align_up(new_top);
const size_t cr_words = pointer_delta(nt_aligned_up, dense_prefix_end); const size_t cr_words = pointer_delta(nt_aligned_up, dense_prefix_end);
tty->print_cr("id=%d cap=" SIZE_FORMAT " dp=" PTR_FORMAT " " log_develop_trace(gc, compaction, phases)(
"dp_region=" SIZE_FORMAT " " "dp_count=" SIZE_FORMAT " " "id=%d cap=" SIZE_FORMAT " dp=" PTR_FORMAT " "
"cr_count=" SIZE_FORMAT " " "nt=" PTR_FORMAT, "dp_region=" SIZE_FORMAT " " "dp_count=" SIZE_FORMAT " "
id, space->capacity_in_words(), p2i(dense_prefix_end), "cr_count=" SIZE_FORMAT " " "nt=" PTR_FORMAT,
dp_region, dp_words / region_size, id, space->capacity_in_words(), p2i(dense_prefix_end),
cr_words / region_size, p2i(new_top)); dp_region, dp_words / region_size,
cr_words / region_size, p2i(new_top));
} }
} }
@ -1582,29 +1559,27 @@ void PSParallelCompact::summary_phase_msg(SpaceId dst_space_id,
SpaceId src_space_id, SpaceId src_space_id,
HeapWord* src_beg, HeapWord* src_end) HeapWord* src_beg, HeapWord* src_end)
{ {
if (TraceParallelOldGCSummaryPhase) { log_develop_trace(gc, compaction, phases)(
tty->print_cr("summarizing %d [%s] into %d [%s]: " "Summarizing %d [%s] into %d [%s]: "
"src=" PTR_FORMAT "-" PTR_FORMAT " " "src=" PTR_FORMAT "-" PTR_FORMAT " "
SIZE_FORMAT "-" SIZE_FORMAT " " SIZE_FORMAT "-" SIZE_FORMAT " "
"dst=" PTR_FORMAT "-" PTR_FORMAT " " "dst=" PTR_FORMAT "-" PTR_FORMAT " "
SIZE_FORMAT "-" SIZE_FORMAT, SIZE_FORMAT "-" SIZE_FORMAT,
src_space_id, space_names[src_space_id], src_space_id, space_names[src_space_id],
dst_space_id, space_names[dst_space_id], dst_space_id, space_names[dst_space_id],
p2i(src_beg), p2i(src_end), p2i(src_beg), p2i(src_end),
_summary_data.addr_to_region_idx(src_beg), _summary_data.addr_to_region_idx(src_beg),
_summary_data.addr_to_region_idx(src_end), _summary_data.addr_to_region_idx(src_end),
p2i(dst_beg), p2i(dst_end), p2i(dst_beg), p2i(dst_end),
_summary_data.addr_to_region_idx(dst_beg), _summary_data.addr_to_region_idx(dst_beg),
_summary_data.addr_to_region_idx(dst_end)); _summary_data.addr_to_region_idx(dst_end));
}
} }
#endif // #ifndef PRODUCT #endif // #ifndef PRODUCT
void PSParallelCompact::summary_phase(ParCompactionManager* cm, void PSParallelCompact::summary_phase(ParCompactionManager* cm,
bool maximum_compaction) bool maximum_compaction)
{ {
GCTraceTime tm("summary phase", print_phases(), true, &_gc_timer); GCTraceTime(Trace, gc, phases) tm("Summary Phase", &_gc_timer);
// trace("2");
#ifdef ASSERT #ifdef ASSERT
if (TraceParallelOldGCMarkingPhase) { if (TraceParallelOldGCMarkingPhase) {
@ -1620,14 +1595,9 @@ void PSParallelCompact::summary_phase(ParCompactionManager* cm,
// Quick summarization of each space into itself, to see how much is live. // Quick summarization of each space into itself, to see how much is live.
summarize_spaces_quick(); summarize_spaces_quick();
if (TraceParallelOldGCSummaryPhase) { log_develop_trace(gc, compaction, phases)("summary phase: after summarizing each space to self");
tty->print_cr("summary_phase: after summarizing each space to self"); NOT_PRODUCT(print_region_ranges());
Universe::print(); NOT_PRODUCT(print_initial_summary_data(_summary_data, _space_info));
NOT_PRODUCT(print_region_ranges());
if (Verbose) {
NOT_PRODUCT(print_initial_summary_data(_summary_data, _space_info));
}
}
// The amount of live data that will end up in old space (assuming it fits). // The amount of live data that will end up in old space (assuming it fits).
size_t old_space_total_live = 0; size_t old_space_total_live = 0;
@ -1701,14 +1671,9 @@ void PSParallelCompact::summary_phase(ParCompactionManager* cm,
} }
} }
if (TraceParallelOldGCSummaryPhase) { log_develop_trace(gc, compaction, phases)("Summary_phase: after final summarization");
tty->print_cr("summary_phase: after final summarization"); NOT_PRODUCT(print_region_ranges());
Universe::print(); NOT_PRODUCT(print_initial_summary_data(_summary_data, _space_info));
NOT_PRODUCT(print_region_ranges());
if (Verbose) {
NOT_PRODUCT(print_generic_summary_data(_summary_data, _space_info));
}
}
} }
// This method should contain all heap-specific policy for invoking a full // This method should contain all heap-specific policy for invoking a full
@ -1783,20 +1748,16 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) {
heap->pre_full_gc_dump(&_gc_timer); heap->pre_full_gc_dump(&_gc_timer);
_print_phases = PrintGCDetails && PrintParallelOldGCPhaseTimes;
// Make sure data structures are sane, make the heap parsable, and do other // Make sure data structures are sane, make the heap parsable, and do other
// miscellaneous bookkeeping. // miscellaneous bookkeeping.
PreGCValues pre_gc_values; pre_compact();
pre_compact(&pre_gc_values);
PreGCValues pre_gc_values(heap);
// Get the compaction manager reserved for the VM thread. // Get the compaction manager reserved for the VM thread.
ParCompactionManager* const vmthread_cm = ParCompactionManager* const vmthread_cm =
ParCompactionManager::manager_array(gc_task_manager()->workers()); ParCompactionManager::manager_array(gc_task_manager()->workers());
// Place after pre_compact() where the number of invocations is incremented.
AdaptiveSizePolicyOutput(size_policy, heap->total_collections());
{ {
ResourceMark rm; ResourceMark rm;
HandleMark hm; HandleMark hm;
@ -1805,8 +1766,8 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) {
gc_task_manager()->set_active_gang(); gc_task_manager()->set_active_gang();
gc_task_manager()->task_idle_workers(); gc_task_manager()->task_idle_workers();
TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); GCTraceCPUTime tcpu;
GCTraceTime t1(GCCauseString("Full GC", gc_cause), PrintGC, !PrintGCDetails, NULL); GCTraceTime(Info, gc) tm("Pause Full", NULL, gc_cause, true);
TraceCollectorStats tcs(counters()); TraceCollectorStats tcs(counters());
TraceMemoryManagerStats tms(true /* Full GC */,gc_cause); TraceMemoryManagerStats tms(true /* Full GC */,gc_cause);
@ -1853,17 +1814,9 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) {
size_policy->major_collection_end(old_gen->used_in_bytes(), gc_cause); size_policy->major_collection_end(old_gen->used_in_bytes(), gc_cause);
if (UseAdaptiveSizePolicy) { if (UseAdaptiveSizePolicy) {
if (PrintAdaptiveSizePolicy) { log_debug(gc, ergo)("AdaptiveSizeStart: collection: %d ", heap->total_collections());
gclog_or_tty->print("AdaptiveSizeStart: "); log_trace(gc, ergo)("old_gen_capacity: " SIZE_FORMAT " young_gen_capacity: " SIZE_FORMAT,
gclog_or_tty->stamp(); old_gen->capacity_in_bytes(), young_gen->capacity_in_bytes());
gclog_or_tty->print_cr(" collection: %d ",
heap->total_collections());
if (Verbose) {
gclog_or_tty->print("old_gen_capacity: " SIZE_FORMAT
" young_gen_capacity: " SIZE_FORMAT,
old_gen->capacity_in_bytes(), young_gen->capacity_in_bytes());
}
}
// Don't check if the size_policy is ready here. Let // Don't check if the size_policy is ready here. Let
// the size_policy check that internally. // the size_policy check that internally.
@ -1921,10 +1874,8 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) {
heap->resize_young_gen(size_policy->calculated_eden_size_in_bytes(), heap->resize_young_gen(size_policy->calculated_eden_size_in_bytes(),
size_policy->calculated_survivor_size_in_bytes()); size_policy->calculated_survivor_size_in_bytes());
} }
if (PrintAdaptiveSizePolicy) {
gclog_or_tty->print_cr("AdaptiveSizeStop: collection: %d ", log_debug(gc, ergo)("AdaptiveSizeStop: collection: %d ", heap->total_collections());
heap->total_collections());
}
} }
if (UsePerfData) { if (UsePerfData) {
@ -1939,20 +1890,14 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) {
// Resize the metaspace capacity after a collection // Resize the metaspace capacity after a collection
MetaspaceGC::compute_new_size(); MetaspaceGC::compute_new_size();
if (TraceOldGenTime) accumulated_time()->stop(); if (TraceOldGenTime) {
accumulated_time()->stop();
if (PrintGC) {
if (PrintGCDetails) {
// No GC timestamp here. This is after GC so it would be confusing.
young_gen->print_used_change(pre_gc_values.young_gen_used());
old_gen->print_used_change(pre_gc_values.old_gen_used());
heap->print_heap_change(pre_gc_values.heap_used());
MetaspaceAux::print_metaspace_change(pre_gc_values.metadata_used());
} else {
heap->print_heap_change(pre_gc_values.heap_used());
}
} }
young_gen->print_used_change(pre_gc_values.young_gen_used());
old_gen->print_used_change(pre_gc_values.old_gen_used());
MetaspaceAux::print_metaspace_change(pre_gc_values.metadata_used());
// Track memory usage and detect low memory // Track memory usage and detect low memory
MemoryService::track_memory_usage(); MemoryService::track_memory_usage();
heap->update_counters(); heap->update_counters();
@ -1970,7 +1915,7 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) {
if (VerifyAfterGC && heap->total_collections() >= VerifyGCStartAt) { if (VerifyAfterGC && heap->total_collections() >= VerifyGCStartAt) {
HandleMark hm; // Discard invalid handles created during verification HandleMark hm; // Discard invalid handles created during verification
Universe::verify(" VerifyAfterGC:"); Universe::verify("After GC");
} }
// Re-verify object start arrays // Re-verify object start arrays
@ -1990,13 +1935,10 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) {
heap->print_heap_after_gc(); heap->print_heap_after_gc();
heap->trace_heap_after_gc(&_gc_tracer); heap->trace_heap_after_gc(&_gc_tracer);
if (PrintGCTaskTimeStamps) { log_debug(gc, task, time)("VM-Thread " JLONG_FORMAT " " JLONG_FORMAT " " JLONG_FORMAT,
gclog_or_tty->print_cr("VM-Thread " JLONG_FORMAT " " JLONG_FORMAT " " marking_start.ticks(), compaction_start.ticks(),
JLONG_FORMAT, collection_exit.ticks());
marking_start.ticks(), compaction_start.ticks(), gc_task_manager()->print_task_time_stamps();
collection_exit.ticks());
gc_task_manager()->print_task_time_stamps();
}
heap->post_full_gc_dump(&_gc_timer); heap->post_full_gc_dump(&_gc_timer);
@ -2004,6 +1946,8 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) {
ParallelTaskTerminator::print_termination_counts(); ParallelTaskTerminator::print_termination_counts();
#endif #endif
AdaptiveSizePolicyOutput::print(size_policy, heap->total_collections());
_gc_timer.register_gc_end(); _gc_timer.register_gc_end();
_gc_tracer.report_dense_prefix(dense_prefix(old_space_id)); _gc_tracer.report_dense_prefix(dense_prefix(old_space_id));
@ -2050,8 +1994,7 @@ bool PSParallelCompact::absorb_live_data_from_eden(PSAdaptiveSizePolicy* size_po
return false; // Respect young gen minimum size. return false; // Respect young gen minimum size.
} }
if (TraceAdaptiveGCBoundary && Verbose) { log_trace(heap, ergo)(" absorbing " SIZE_FORMAT "K: "
gclog_or_tty->print(" absorbing " SIZE_FORMAT "K: "
"eden " SIZE_FORMAT "K->" SIZE_FORMAT "K " "eden " SIZE_FORMAT "K->" SIZE_FORMAT "K "
"from " SIZE_FORMAT "K, to " SIZE_FORMAT "K " "from " SIZE_FORMAT "K, to " SIZE_FORMAT "K "
"young_gen " SIZE_FORMAT "K->" SIZE_FORMAT "K ", "young_gen " SIZE_FORMAT "K->" SIZE_FORMAT "K ",
@ -2060,7 +2003,6 @@ bool PSParallelCompact::absorb_live_data_from_eden(PSAdaptiveSizePolicy* size_po
young_gen->from_space()->used_in_bytes() / K, young_gen->from_space()->used_in_bytes() / K,
young_gen->to_space()->used_in_bytes() / K, young_gen->to_space()->used_in_bytes() / K,
young_gen->capacity_in_bytes() / K, new_young_size / K); young_gen->capacity_in_bytes() / K, new_young_size / K);
}
// Fill the unused part of the old gen. // Fill the unused part of the old gen.
MutableSpace* const old_space = old_gen->object_space(); MutableSpace* const old_space = old_gen->object_space();
@ -2110,7 +2052,7 @@ void PSParallelCompact::marking_phase(ParCompactionManager* cm,
bool maximum_heap_compaction, bool maximum_heap_compaction,
ParallelOldTracer *gc_tracer) { ParallelOldTracer *gc_tracer) {
// Recursively traverse all live objects and mark them // Recursively traverse all live objects and mark them
GCTraceTime tm("marking phase", print_phases(), true, &_gc_timer); GCTraceTime(Trace, gc, phases) tm("Marking Phase", &_gc_timer);
ParallelScavengeHeap* heap = ParallelScavengeHeap::heap(); ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
uint parallel_gc_threads = heap->gc_task_manager()->workers(); uint parallel_gc_threads = heap->gc_task_manager()->workers();
@ -2125,7 +2067,7 @@ void PSParallelCompact::marking_phase(ParCompactionManager* cm,
ClassLoaderDataGraph::clear_claimed_marks(); ClassLoaderDataGraph::clear_claimed_marks();
{ {
GCTraceTime tm_m("par mark", print_phases(), true, &_gc_timer); GCTraceTime(Trace, gc, phases) tm("Par Mark", &_gc_timer);
ParallelScavengeHeap::ParStrongRootsScope psrs; ParallelScavengeHeap::ParStrongRootsScope psrs;
@ -2154,7 +2096,7 @@ void PSParallelCompact::marking_phase(ParCompactionManager* cm,
// Process reference objects found during marking // Process reference objects found during marking
{ {
GCTraceTime tm_r("reference processing", print_phases(), true, &_gc_timer); GCTraceTime(Trace, gc, phases) tm("Reference Processing", &_gc_timer);
ReferenceProcessorStats stats; ReferenceProcessorStats stats;
if (ref_processor()->processing_is_mt()) { if (ref_processor()->processing_is_mt()) {
@ -2171,7 +2113,7 @@ void PSParallelCompact::marking_phase(ParCompactionManager* cm,
gc_tracer->report_gc_reference_stats(stats); gc_tracer->report_gc_reference_stats(stats);
} }
GCTraceTime tm_c("class unloading", print_phases(), true, &_gc_timer); GCTraceTime(Trace, gc) tm_m("Class Unloading", &_gc_timer);
// This is the point where the entire marking should have completed. // This is the point where the entire marking should have completed.
assert(cm->marking_stacks_empty(), "Marking should have completed"); assert(cm->marking_stacks_empty(), "Marking should have completed");
@ -2202,7 +2144,7 @@ static PSAlwaysTrueClosure always_true;
void PSParallelCompact::adjust_roots() { void PSParallelCompact::adjust_roots() {
// Adjust the pointers to reflect the new locations // Adjust the pointers to reflect the new locations
GCTraceTime tm("adjust roots", print_phases(), true, &_gc_timer); GCTraceTime(Trace, gc, phases) tm("Adjust Roots", &_gc_timer);
// Need new claim bits when tracing through and adjusting pointers. // Need new claim bits when tracing through and adjusting pointers.
ClassLoaderDataGraph::clear_claimed_marks(); ClassLoaderDataGraph::clear_claimed_marks();
@ -2235,10 +2177,49 @@ void PSParallelCompact::adjust_roots() {
PSScavenge::reference_processor()->weak_oops_do(adjust_pointer_closure()); PSScavenge::reference_processor()->weak_oops_do(adjust_pointer_closure());
} }
// Helper class to print 8 region numbers per line and then print the total at the end.
class FillableRegionLogger : public StackObj {
private:
LogHandle(gc, compaction) log;
static const int LineLength = 8;
size_t _regions[LineLength];
int _next_index;
bool _enabled;
size_t _total_regions;
public:
FillableRegionLogger() : _next_index(0), _total_regions(0), _enabled(develop_log_is_enabled(Trace, gc, compaction)) { }
~FillableRegionLogger() {
log.trace(SIZE_FORMAT " initially fillable regions", _total_regions);
}
void print_line() {
if (!_enabled || _next_index == 0) {
return;
}
FormatBuffer<> line("Fillable: ");
for (int i = 0; i < _next_index; i++) {
line.append(" " SIZE_FORMAT_W(7), _regions[i]);
}
log.trace("%s", line.buffer());
_next_index = 0;
}
void handle(size_t region) {
if (!_enabled) {
return;
}
_regions[_next_index++] = region;
if (_next_index == LineLength) {
print_line();
}
_total_regions++;
}
};
void PSParallelCompact::enqueue_region_draining_tasks(GCTaskQueue* q, void PSParallelCompact::enqueue_region_draining_tasks(GCTaskQueue* q,
uint parallel_gc_threads) uint parallel_gc_threads)
{ {
GCTraceTime tm("drain task setup", print_phases(), true, &_gc_timer); GCTraceTime(Trace, gc, phases) tm("Drain Task Setup", &_gc_timer);
// Find the threads that are active // Find the threads that are active
unsigned int which = 0; unsigned int which = 0;
@ -2263,13 +2244,13 @@ void PSParallelCompact::enqueue_region_draining_tasks(GCTaskQueue* q,
const ParallelCompactData& sd = PSParallelCompact::summary_data(); const ParallelCompactData& sd = PSParallelCompact::summary_data();
size_t fillable_regions = 0; // A count for diagnostic purposes.
// A region index which corresponds to the tasks created above. // A region index which corresponds to the tasks created above.
// "which" must be 0 <= which < task_count // "which" must be 0 <= which < task_count
which = 0; which = 0;
// id + 1 is used to test termination so unsigned can // id + 1 is used to test termination so unsigned can
// be used with an old_space_id == 0. // be used with an old_space_id == 0.
FillableRegionLogger region_logger;
for (unsigned int id = to_space_id; id + 1 > old_space_id; --id) { for (unsigned int id = to_space_id; id + 1 > old_space_id; --id) {
SpaceInfo* const space_info = _space_info + id; SpaceInfo* const space_info = _space_info + id;
MutableSpace* const space = space_info->space(); MutableSpace* const space = space_info->space();
@ -2282,16 +2263,7 @@ void PSParallelCompact::enqueue_region_draining_tasks(GCTaskQueue* q,
for (size_t cur = end_region - 1; cur + 1 > beg_region; --cur) { for (size_t cur = end_region - 1; cur + 1 > beg_region; --cur) {
if (sd.region(cur)->claim_unsafe()) { if (sd.region(cur)->claim_unsafe()) {
ParCompactionManager::region_list_push(which, cur); ParCompactionManager::region_list_push(which, cur);
region_logger.handle(cur);
if (TraceParallelOldGCCompactionPhase && Verbose) {
const size_t count_mod_8 = fillable_regions & 7;
if (count_mod_8 == 0) gclog_or_tty->print("fillable: ");
gclog_or_tty->print(" " SIZE_FORMAT_W(7), cur);
if (count_mod_8 == 7) gclog_or_tty->cr();
}
NOT_PRODUCT(++fillable_regions;)
// Assign regions to tasks in round-robin fashion. // Assign regions to tasks in round-robin fashion.
if (++which == task_count) { if (++which == task_count) {
assert(which <= parallel_gc_threads, assert(which <= parallel_gc_threads,
@ -2300,11 +2272,7 @@ void PSParallelCompact::enqueue_region_draining_tasks(GCTaskQueue* q,
} }
} }
} }
} region_logger.print_line();
if (TraceParallelOldGCCompactionPhase) {
if (Verbose && (fillable_regions & 7) != 0) gclog_or_tty->cr();
gclog_or_tty->print_cr(SIZE_FORMAT " initially fillable regions", fillable_regions);
} }
} }
@ -2312,7 +2280,7 @@ void PSParallelCompact::enqueue_region_draining_tasks(GCTaskQueue* q,
void PSParallelCompact::enqueue_dense_prefix_tasks(GCTaskQueue* q, void PSParallelCompact::enqueue_dense_prefix_tasks(GCTaskQueue* q,
uint parallel_gc_threads) { uint parallel_gc_threads) {
GCTraceTime tm("dense prefix task setup", print_phases(), true, &_gc_timer); GCTraceTime(Trace, gc, phases) tm("Dense Prefix Task Setup", &_gc_timer);
ParallelCompactData& sd = PSParallelCompact::summary_data(); ParallelCompactData& sd = PSParallelCompact::summary_data();
@ -2394,7 +2362,7 @@ void PSParallelCompact::enqueue_region_stealing_tasks(
GCTaskQueue* q, GCTaskQueue* q,
ParallelTaskTerminator* terminator_ptr, ParallelTaskTerminator* terminator_ptr,
uint parallel_gc_threads) { uint parallel_gc_threads) {
GCTraceTime tm("steal task setup", print_phases(), true, &_gc_timer); GCTraceTime(Trace, gc, phases) tm("Steal Task Setup", &_gc_timer);
// Once a thread has drained it's stack, it should try to steal regions from // Once a thread has drained it's stack, it should try to steal regions from
// other threads. // other threads.
@ -2408,9 +2376,15 @@ void PSParallelCompact::enqueue_region_stealing_tasks(
#ifdef ASSERT #ifdef ASSERT
// Write a histogram of the number of times the block table was filled for a // Write a histogram of the number of times the block table was filled for a
// region. // region.
void PSParallelCompact::write_block_fill_histogram(outputStream* const out) void PSParallelCompact::write_block_fill_histogram()
{ {
if (!TraceParallelOldGCCompactionPhase) return; if (!develop_log_is_enabled(Trace, gc, compaction)) {
return;
}
LogHandle(gc, compaction) log;
ResourceMark rm;
outputStream* out = log.trace_stream();
typedef ParallelCompactData::RegionData rd_t; typedef ParallelCompactData::RegionData rd_t;
ParallelCompactData& sd = summary_data(); ParallelCompactData& sd = summary_data();
@ -2429,7 +2403,7 @@ void PSParallelCompact::write_block_fill_histogram(outputStream* const out)
for (const rd_t* cur = beg; cur < end; ++cur) { for (const rd_t* cur = beg; cur < end; ++cur) {
++histo[MIN2(cur->blocks_filled_count(), histo_len - 1)]; ++histo[MIN2(cur->blocks_filled_count(), histo_len - 1)];
} }
out->print("%u %-4s" SIZE_FORMAT_W(5), id, space_names[id], region_cnt); out->print("Block fill histogram: %u %-4s" SIZE_FORMAT_W(5), id, space_names[id], region_cnt);
for (size_t i = 0; i < histo_len; ++i) { for (size_t i = 0; i < histo_len; ++i) {
out->print(" " SIZE_FORMAT_W(5) " %5.1f%%", out->print(" " SIZE_FORMAT_W(5) " %5.1f%%",
histo[i], 100.0 * histo[i] / region_cnt); histo[i], 100.0 * histo[i] / region_cnt);
@ -2441,8 +2415,7 @@ void PSParallelCompact::write_block_fill_histogram(outputStream* const out)
#endif // #ifdef ASSERT #endif // #ifdef ASSERT
void PSParallelCompact::compact() { void PSParallelCompact::compact() {
// trace("5"); GCTraceTime(Trace, gc, phases) tm("Compaction Phase", &_gc_timer);
GCTraceTime tm("compaction phase", print_phases(), true, &_gc_timer);
ParallelScavengeHeap* heap = ParallelScavengeHeap::heap(); ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
PSOldGen* old_gen = heap->old_gen(); PSOldGen* old_gen = heap->old_gen();
@ -2458,7 +2431,7 @@ void PSParallelCompact::compact() {
enqueue_region_stealing_tasks(q, &terminator, active_gc_threads); enqueue_region_stealing_tasks(q, &terminator, active_gc_threads);
{ {
GCTraceTime tm_pc("par compact", print_phases(), true, &_gc_timer); GCTraceTime(Trace, gc, phases) tm("Par Compact", &_gc_timer);
gc_task_manager()->execute_and_wait(q); gc_task_manager()->execute_and_wait(q);
@ -2472,14 +2445,14 @@ void PSParallelCompact::compact() {
{ {
// Update the deferred objects, if any. Any compaction manager can be used. // Update the deferred objects, if any. Any compaction manager can be used.
GCTraceTime tm_du("deferred updates", print_phases(), true, &_gc_timer); GCTraceTime(Trace, gc, phases) tm("Deferred Updates", &_gc_timer);
ParCompactionManager* cm = ParCompactionManager::manager_array(0); ParCompactionManager* cm = ParCompactionManager::manager_array(0);
for (unsigned int id = old_space_id; id < last_space_id; ++id) { for (unsigned int id = old_space_id; id < last_space_id; ++id) {
update_deferred_objects(cm, SpaceId(id)); update_deferred_objects(cm, SpaceId(id));
} }
} }
DEBUG_ONLY(write_block_fill_histogram(gclog_or_tty)); DEBUG_ONLY(write_block_fill_histogram());
} }
#ifdef ASSERT #ifdef ASSERT
@ -3108,18 +3081,13 @@ template <class T> static void trace_reference_gc(const char *s, oop obj,
T* referent_addr, T* referent_addr,
T* next_addr, T* next_addr,
T* discovered_addr) { T* discovered_addr) {
if(TraceReferenceGC && PrintGCDetails) { log_develop_trace(gc, ref)("%s obj " PTR_FORMAT, s, p2i(obj));
gclog_or_tty->print_cr("%s obj " PTR_FORMAT, s, p2i(obj)); log_develop_trace(gc, ref)(" referent_addr/* " PTR_FORMAT " / " PTR_FORMAT,
gclog_or_tty->print_cr(" referent_addr/* " PTR_FORMAT " / " p2i(referent_addr), referent_addr ? p2i(oopDesc::load_decode_heap_oop(referent_addr)) : NULL);
PTR_FORMAT, p2i(referent_addr), log_develop_trace(gc, ref)(" next_addr/* " PTR_FORMAT " / " PTR_FORMAT,
referent_addr ? p2i(oopDesc::load_decode_heap_oop(referent_addr)) : NULL); p2i(next_addr), next_addr ? p2i(oopDesc::load_decode_heap_oop(next_addr)) : NULL);
gclog_or_tty->print_cr(" next_addr/* " PTR_FORMAT " / " log_develop_trace(gc, ref)(" discovered_addr/* " PTR_FORMAT " / " PTR_FORMAT,
PTR_FORMAT, p2i(next_addr), p2i(discovered_addr), discovered_addr ? p2i(oopDesc::load_decode_heap_oop(discovered_addr)) : NULL);
next_addr ? p2i(oopDesc::load_decode_heap_oop(next_addr)) : NULL);
gclog_or_tty->print_cr(" discovered_addr/* " PTR_FORMAT " / "
PTR_FORMAT, p2i(discovered_addr),
discovered_addr ? p2i(oopDesc::load_decode_heap_oop(discovered_addr)) : NULL);
}
} }
#endif #endif

View file

@ -966,7 +966,6 @@ class PSParallelCompact : AllStatic {
static ParallelCompactData _summary_data; static ParallelCompactData _summary_data;
static IsAliveClosure _is_alive_closure; static IsAliveClosure _is_alive_closure;
static SpaceInfo _space_info[last_space_id]; static SpaceInfo _space_info[last_space_id];
static bool _print_phases;
static AdjustPointerClosure _adjust_pointer_closure; static AdjustPointerClosure _adjust_pointer_closure;
static AdjustKlassClosure _adjust_klass_closure; static AdjustKlassClosure _adjust_klass_closure;
@ -989,13 +988,10 @@ class PSParallelCompact : AllStatic {
static void initialize_space_info(); static void initialize_space_info();
// Return true if details about individual phases should be printed.
static inline bool print_phases();
// Clear the marking bitmap and summary data that cover the specified space. // Clear the marking bitmap and summary data that cover the specified space.
static void clear_data_covering_space(SpaceId id); static void clear_data_covering_space(SpaceId id);
static void pre_compact(PreGCValues* pre_gc_values); static void pre_compact();
static void post_compact(); static void post_compact();
// Mark live objects // Mark live objects
@ -1069,7 +1065,7 @@ class PSParallelCompact : AllStatic {
// Adjust addresses in roots. Does not adjust addresses in heap. // Adjust addresses in roots. Does not adjust addresses in heap.
static void adjust_roots(); static void adjust_roots();
DEBUG_ONLY(static void write_block_fill_histogram(outputStream* const out);) DEBUG_ONLY(static void write_block_fill_histogram();)
// Move objects to new locations. // Move objects to new locations.
static void compact_perm(ParCompactionManager* cm); static void compact_perm(ParCompactionManager* cm);
@ -1260,10 +1256,6 @@ inline bool PSParallelCompact::is_marked(oop obj) {
return mark_bitmap()->is_marked(obj); return mark_bitmap()->is_marked(obj);
} }
inline bool PSParallelCompact::print_phases() {
return _print_phases;
}
inline double PSParallelCompact::normal_distribution(double density) { inline double PSParallelCompact::normal_distribution(double density) {
assert(_dwl_initialized, "uninitialized"); assert(_dwl_initialized, "uninitialized");
const double squared_term = (density - _dwl_mean) / _dwl_std_dev; const double squared_term = (density - _dwl_mean) / _dwl_std_dev;

View file

@ -30,6 +30,7 @@
#include "gc/parallel/psScavenge.inline.hpp" #include "gc/parallel/psScavenge.inline.hpp"
#include "gc/shared/gcTrace.hpp" #include "gc/shared/gcTrace.hpp"
#include "gc/shared/taskqueue.inline.hpp" #include "gc/shared/taskqueue.inline.hpp"
#include "logging/log.hpp"
#include "memory/allocation.inline.hpp" #include "memory/allocation.inline.hpp"
#include "memory/memRegion.hpp" #include "memory/memRegion.hpp"
#include "memory/padded.inline.hpp" #include "memory/padded.inline.hpp"
@ -99,7 +100,7 @@ void PSPromotionManager::pre_scavenge() {
bool PSPromotionManager::post_scavenge(YoungGCTracer& gc_tracer) { bool PSPromotionManager::post_scavenge(YoungGCTracer& gc_tracer) {
bool promotion_failure_occurred = false; bool promotion_failure_occurred = false;
TASKQUEUE_STATS_ONLY(if (PrintTaskqueue) print_taskqueue_stats()); TASKQUEUE_STATS_ONLY(print_taskqueue_stats());
for (uint i = 0; i < ParallelGCThreads + 1; i++) { for (uint i = 0; i < ParallelGCThreads + 1; i++) {
PSPromotionManager* manager = manager_array(i); PSPromotionManager* manager = manager_array(i);
assert(manager->claimed_stack_depth()->is_empty(), "should be empty"); assert(manager->claimed_stack_depth()->is_empty(), "should be empty");
@ -128,7 +129,13 @@ static const char* const pm_stats_hdr[] = {
}; };
void void
PSPromotionManager::print_taskqueue_stats(outputStream* const out) { PSPromotionManager::print_taskqueue_stats() {
if (!develop_log_is_enabled(Trace, gc, task, stats)) {
return;
}
LogHandle(gc, task, stats) log;
ResourceMark rm;
outputStream* out = log.trace_stream();
out->print_cr("== GC Tasks Stats, GC %3d", out->print_cr("== GC Tasks Stats, GC %3d",
ParallelScavengeHeap::heap()->total_collections()); ParallelScavengeHeap::heap()->total_collections());
@ -368,12 +375,7 @@ static void oop_ps_push_contents_specialized(oop obj, InstanceRefKlass *klass, P
T next_oop = oopDesc::load_heap_oop(next_addr); T next_oop = oopDesc::load_heap_oop(next_addr);
if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active" if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active"
T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj); T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
debug_only( log_develop_trace(gc, ref)(" Process discovered as normal " PTR_FORMAT, p2i(discovered_addr));
if(TraceReferenceGC && PrintGCDetails) {
gclog_or_tty->print_cr(" Process discovered as normal "
PTR_FORMAT, p2i(discovered_addr));
}
)
if (PSScavenge::should_scavenge(discovered_addr)) { if (PSScavenge::should_scavenge(discovered_addr)) {
pm->claim_or_forward_depth(discovered_addr); pm->claim_or_forward_depth(discovered_addr);
} }
@ -430,13 +432,7 @@ oop PSPromotionManager::oop_promotion_failed(oop obj, markOop obj_mark) {
obj = obj->forwardee(); obj = obj->forwardee();
} }
if (TraceScavenge) { log_develop_trace(gc, scavenge)("{promotion-failure %s " PTR_FORMAT " (%d)}", obj->klass()->internal_name(), p2i(obj), obj->size());
gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " (%d)}",
"promotion-failure",
obj->klass()->internal_name(),
p2i(obj), obj->size());
}
return obj; return obj;
} }

View file

@ -65,7 +65,7 @@ class PSPromotionManager VALUE_OBJ_CLASS_SPEC {
size_t _array_chunks_processed; size_t _array_chunks_processed;
void print_local_stats(outputStream* const out, uint i) const; void print_local_stats(outputStream* const out, uint i) const;
static void print_taskqueue_stats(outputStream* const out = gclog_or_tty); static void print_taskqueue_stats();
void reset_stats(); void reset_stats();
#endif // TASKQUEUE_STATS #endif // TASKQUEUE_STATS

View file

@ -31,6 +31,7 @@
#include "gc/parallel/psPromotionManager.hpp" #include "gc/parallel/psPromotionManager.hpp"
#include "gc/parallel/psScavenge.hpp" #include "gc/parallel/psScavenge.hpp"
#include "gc/shared/taskqueue.inline.hpp" #include "gc/shared/taskqueue.inline.hpp"
#include "logging/log.hpp"
#include "oops/oop.inline.hpp" #include "oops/oop.inline.hpp"
inline PSPromotionManager* PSPromotionManager::manager_array(uint index) { inline PSPromotionManager* PSPromotionManager::manager_array(uint index) {
@ -262,11 +263,9 @@ inline oop PSPromotionManager::copy_to_survivor_space(oop o) {
// This code must come after the CAS test, or it will print incorrect // This code must come after the CAS test, or it will print incorrect
// information. // information.
if (TraceScavenge) { log_develop_trace(gc, scavenge)("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",
gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}", should_scavenge(&new_obj) ? "copying" : "tenuring",
should_scavenge(&new_obj) ? "copying" : "tenuring", new_obj->klass()->internal_name(), p2i((void *)o), p2i((void *)new_obj), new_obj->size());
new_obj->klass()->internal_name(), p2i((void *)o), p2i((void *)new_obj), new_obj->size());
}
return new_obj; return new_obj;
} }
@ -285,10 +284,10 @@ inline void PSPromotionManager::copy_and_push_safe_barrier(T* p) {
// This code must come after the CAS test, or it will print incorrect // This code must come after the CAS test, or it will print incorrect
// information. // information.
if (TraceScavenge && o->is_forwarded()) { if (develop_log_is_enabled(Trace, gc, scavenge) && o->is_forwarded()) {
gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}", log_develop_trace(gc, scavenge)("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",
"forwarding", "forwarding",
new_obj->klass()->internal_name(), p2i((void *)o), p2i((void *)new_obj), new_obj->size()); new_obj->klass()->internal_name(), p2i((void *)o), p2i((void *)new_obj), new_obj->size());
} }
oopDesc::encode_store_heap_oop_not_null(p, new_obj); oopDesc::encode_store_heap_oop_not_null(p, new_obj);

View file

@ -40,12 +40,13 @@
#include "gc/shared/gcLocker.inline.hpp" #include "gc/shared/gcLocker.inline.hpp"
#include "gc/shared/gcTimer.hpp" #include "gc/shared/gcTimer.hpp"
#include "gc/shared/gcTrace.hpp" #include "gc/shared/gcTrace.hpp"
#include "gc/shared/gcTraceTime.hpp" #include "gc/shared/gcTraceTime.inline.hpp"
#include "gc/shared/isGCActiveMark.hpp" #include "gc/shared/isGCActiveMark.hpp"
#include "gc/shared/referencePolicy.hpp" #include "gc/shared/referencePolicy.hpp"
#include "gc/shared/referenceProcessor.hpp" #include "gc/shared/referenceProcessor.hpp"
#include "gc/shared/spaceDecorator.hpp" #include "gc/shared/spaceDecorator.hpp"
#include "memory/resourceArea.hpp" #include "memory/resourceArea.hpp"
#include "logging/log.hpp"
#include "oops/oop.inline.hpp" #include "oops/oop.inline.hpp"
#include "runtime/biasedLocking.hpp" #include "runtime/biasedLocking.hpp"
#include "runtime/fprofiler.hpp" #include "runtime/fprofiler.hpp"
@ -290,8 +291,6 @@ bool PSScavenge::invoke_no_policy() {
heap->increment_total_collections(); heap->increment_total_collections();
AdaptiveSizePolicyOutput(size_policy, heap->total_collections());
if (AdaptiveSizePolicy::should_update_eden_stats(gc_cause)) { if (AdaptiveSizePolicy::should_update_eden_stats(gc_cause)) {
// Gather the feedback data for eden occupancy. // Gather the feedback data for eden occupancy.
young_gen->eden_space()->accumulate_statistics(); young_gen->eden_space()->accumulate_statistics();
@ -303,23 +302,21 @@ bool PSScavenge::invoke_no_policy() {
assert(!NeverTenure || _tenuring_threshold == markOopDesc::max_age + 1, "Sanity"); assert(!NeverTenure || _tenuring_threshold == markOopDesc::max_age + 1, "Sanity");
assert(!AlwaysTenure || _tenuring_threshold == 0, "Sanity"); assert(!AlwaysTenure || _tenuring_threshold == 0, "Sanity");
size_t prev_used = heap->used();
// Fill in TLABs // Fill in TLABs
heap->accumulate_statistics_all_tlabs(); heap->accumulate_statistics_all_tlabs();
heap->ensure_parsability(true); // retire TLABs heap->ensure_parsability(true); // retire TLABs
if (VerifyBeforeGC && heap->total_collections() >= VerifyGCStartAt) { if (VerifyBeforeGC && heap->total_collections() >= VerifyGCStartAt) {
HandleMark hm; // Discard invalid handles created during verification HandleMark hm; // Discard invalid handles created during verification
Universe::verify(" VerifyBeforeGC:"); Universe::verify("Before GC");
} }
{ {
ResourceMark rm; ResourceMark rm;
HandleMark hm; HandleMark hm;
TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); GCTraceCPUTime tcpu;
GCTraceTime t1(GCCauseString("GC", gc_cause), PrintGC, !PrintGCDetails, NULL); GCTraceTime(Info, gc) tm("Pause Young", NULL, gc_cause, true);
TraceCollectorStats tcs(counters()); TraceCollectorStats tcs(counters());
TraceMemoryManagerStats tms(false /* not full GC */,gc_cause); TraceMemoryManagerStats tms(false /* not full GC */,gc_cause);
@ -352,12 +349,7 @@ bool PSScavenge::invoke_no_policy() {
reference_processor()->enable_discovery(); reference_processor()->enable_discovery();
reference_processor()->setup_policy(false); reference_processor()->setup_policy(false);
// We track how much was promoted to the next generation for PreGCValues pre_gc_values(heap);
// the AdaptiveSizePolicy.
size_t old_gen_used_before = old_gen->used_in_bytes();
// For PrintGCDetails
size_t young_gen_used_before = young_gen->used_in_bytes();
// Reset our survivor overflow. // Reset our survivor overflow.
set_survivor_overflow(false); set_survivor_overflow(false);
@ -383,7 +375,7 @@ bool PSScavenge::invoke_no_policy() {
// We'll use the promotion manager again later. // We'll use the promotion manager again later.
PSPromotionManager* promotion_manager = PSPromotionManager::vm_thread_promotion_manager(); PSPromotionManager* promotion_manager = PSPromotionManager::vm_thread_promotion_manager();
{ {
GCTraceTime tm("Scavenge", false, false, &_gc_timer); GCTraceTime(Debug, gc, phases) tm("Scavenge", &_gc_timer);
ParallelScavengeHeap::ParStrongRootsScope psrs; ParallelScavengeHeap::ParStrongRootsScope psrs;
GCTaskQueue* q = GCTaskQueue::create(); GCTaskQueue* q = GCTaskQueue::create();
@ -425,7 +417,7 @@ bool PSScavenge::invoke_no_policy() {
// Process reference objects discovered during scavenge // Process reference objects discovered during scavenge
{ {
GCTraceTime tm("References", false, false, &_gc_timer); GCTraceTime(Debug, gc, phases) tm("References", &_gc_timer);
reference_processor()->setup_policy(false); // not always_clear reference_processor()->setup_policy(false); // not always_clear
reference_processor()->set_active_mt_degree(active_workers); reference_processor()->set_active_mt_degree(active_workers);
@ -454,7 +446,7 @@ bool PSScavenge::invoke_no_policy() {
} }
{ {
GCTraceTime tm("StringTable", false, false, &_gc_timer); GCTraceTime(Debug, gc, phases) tm("StringTable", &_gc_timer);
// Unlink any dead interned Strings and process the remaining live ones. // Unlink any dead interned Strings and process the remaining live ones.
PSScavengeRootsClosure root_closure(promotion_manager); PSScavengeRootsClosure root_closure(promotion_manager);
StringTable::unlink_or_oops_do(&_is_alive_closure, &root_closure); StringTable::unlink_or_oops_do(&_is_alive_closure, &root_closure);
@ -464,9 +456,7 @@ bool PSScavenge::invoke_no_policy() {
promotion_failure_occurred = PSPromotionManager::post_scavenge(_gc_tracer); promotion_failure_occurred = PSPromotionManager::post_scavenge(_gc_tracer);
if (promotion_failure_occurred) { if (promotion_failure_occurred) {
clean_up_failed_promotion(); clean_up_failed_promotion();
if (PrintGC) { log_info(gc)("Promotion failed");
gclog_or_tty->print("--");
}
} }
_gc_tracer.report_tenuring_threshold(tenuring_threshold()); _gc_tracer.report_tenuring_threshold(tenuring_threshold());
@ -483,7 +473,7 @@ bool PSScavenge::invoke_no_policy() {
young_gen->swap_spaces(); young_gen->swap_spaces();
size_t survived = young_gen->from_space()->used_in_bytes(); size_t survived = young_gen->from_space()->used_in_bytes();
size_t promoted = old_gen->used_in_bytes() - old_gen_used_before; size_t promoted = old_gen->used_in_bytes() - pre_gc_values.old_gen_used();
size_policy->update_averages(_survivor_overflow, survived, promoted); size_policy->update_averages(_survivor_overflow, survived, promoted);
// A successful scavenge should restart the GC time limit count which is // A successful scavenge should restart the GC time limit count which is
@ -492,19 +482,9 @@ bool PSScavenge::invoke_no_policy() {
if (UseAdaptiveSizePolicy) { if (UseAdaptiveSizePolicy) {
// Calculate the new survivor size and tenuring threshold // Calculate the new survivor size and tenuring threshold
if (PrintAdaptiveSizePolicy) { log_debug(gc, ergo)("AdaptiveSizeStart: collection: %d ", heap->total_collections());
gclog_or_tty->print("AdaptiveSizeStart: "); log_trace(gc, ergo)("old_gen_capacity: " SIZE_FORMAT " young_gen_capacity: " SIZE_FORMAT,
gclog_or_tty->stamp(); old_gen->capacity_in_bytes(), young_gen->capacity_in_bytes());
gclog_or_tty->print_cr(" collection: %d ",
heap->total_collections());
if (Verbose) {
gclog_or_tty->print("old_gen_capacity: " SIZE_FORMAT
" young_gen_capacity: " SIZE_FORMAT,
old_gen->capacity_in_bytes(), young_gen->capacity_in_bytes());
}
}
if (UsePerfData) { if (UsePerfData) {
PSGCAdaptivePolicyCounters* counters = heap->gc_policy_counters(); PSGCAdaptivePolicyCounters* counters = heap->gc_policy_counters();
@ -538,13 +518,9 @@ bool PSScavenge::invoke_no_policy() {
_tenuring_threshold, _tenuring_threshold,
survivor_limit); survivor_limit);
if (PrintTenuringDistribution) { log_debug(gc, age)("Desired survivor size " SIZE_FORMAT " bytes, new threshold %u (max threshold " UINTX_FORMAT ")",
gclog_or_tty->cr(); size_policy->calculated_survivor_size_in_bytes(),
gclog_or_tty->print_cr("Desired survivor size " SIZE_FORMAT " bytes, new threshold %u" _tenuring_threshold, MaxTenuringThreshold);
" (max threshold " UINTX_FORMAT ")",
size_policy->calculated_survivor_size_in_bytes(),
_tenuring_threshold, MaxTenuringThreshold);
}
if (UsePerfData) { if (UsePerfData) {
PSGCAdaptivePolicyCounters* counters = heap->gc_policy_counters(); PSGCAdaptivePolicyCounters* counters = heap->gc_policy_counters();
@ -602,10 +578,7 @@ bool PSScavenge::invoke_no_policy() {
heap->resize_young_gen(size_policy->calculated_eden_size_in_bytes(), heap->resize_young_gen(size_policy->calculated_eden_size_in_bytes(),
size_policy->calculated_survivor_size_in_bytes()); size_policy->calculated_survivor_size_in_bytes());
if (PrintAdaptiveSizePolicy) { log_debug(gc, ergo)("AdaptiveSizeStop: collection: %d ", heap->total_collections());
gclog_or_tty->print_cr("AdaptiveSizeStop: collection: %d ",
heap->total_collections());
}
} }
// Update the structure of the eden. With NUMA-eden CPU hotplugging or offlining can // Update the structure of the eden. With NUMA-eden CPU hotplugging or offlining can
@ -628,7 +601,7 @@ bool PSScavenge::invoke_no_policy() {
NOT_PRODUCT(reference_processor()->verify_no_references_recorded()); NOT_PRODUCT(reference_processor()->verify_no_references_recorded());
{ {
GCTraceTime tm("Prune Scavenge Root Methods", false, false, &_gc_timer); GCTraceTime(Debug, gc, phases) tm("Prune Scavenge Root Methods", &_gc_timer);
CodeCache::prune_scavenge_root_nmethods(); CodeCache::prune_scavenge_root_nmethods();
} }
@ -649,14 +622,9 @@ bool PSScavenge::invoke_no_policy() {
if (TraceYoungGenTime) accumulated_time()->stop(); if (TraceYoungGenTime) accumulated_time()->stop();
if (PrintGC) { young_gen->print_used_change(pre_gc_values.young_gen_used());
if (PrintGCDetails) { old_gen->print_used_change(pre_gc_values.old_gen_used());
// Don't print a GC timestamp here. This is after the GC so MetaspaceAux::print_metaspace_change(pre_gc_values.metadata_used());
// would be confusing.
young_gen->print_used_change(young_gen_used_before);
}
heap->print_heap_change(prev_used);
}
// Track memory usage and detect low memory // Track memory usage and detect low memory
MemoryService::track_memory_usage(); MemoryService::track_memory_usage();
@ -667,7 +635,7 @@ bool PSScavenge::invoke_no_policy() {
if (VerifyAfterGC && heap->total_collections() >= VerifyGCStartAt) { if (VerifyAfterGC && heap->total_collections() >= VerifyGCStartAt) {
HandleMark hm; // Discard invalid handles created during verification HandleMark hm; // Discard invalid handles created during verification
Universe::verify(" VerifyAfterGC:"); Universe::verify("After GC");
} }
heap->print_heap_after_gc(); heap->print_heap_after_gc();
@ -675,17 +643,16 @@ bool PSScavenge::invoke_no_policy() {
scavenge_exit.update(); scavenge_exit.update();
if (PrintGCTaskTimeStamps) { log_debug(gc, task, time)("VM-Thread " JLONG_FORMAT " " JLONG_FORMAT " " JLONG_FORMAT,
tty->print_cr("VM-Thread " JLONG_FORMAT " " JLONG_FORMAT " " JLONG_FORMAT, scavenge_entry.ticks(), scavenge_midpoint.ticks(),
scavenge_entry.ticks(), scavenge_midpoint.ticks(), scavenge_exit.ticks());
scavenge_exit.ticks()); gc_task_manager()->print_task_time_stamps();
gc_task_manager()->print_task_time_stamps();
}
#ifdef TRACESPINNING #ifdef TRACESPINNING
ParallelTaskTerminator::print_termination_counts(); ParallelTaskTerminator::print_termination_counts();
#endif #endif
AdaptiveSizePolicyOutput::print(size_policy, heap->total_collections());
_gc_timer.register_gc_end(); _gc_timer.register_gc_end();
@ -708,9 +675,7 @@ void PSScavenge::clean_up_failed_promotion() {
PSPromotionFailedClosure unforward_closure; PSPromotionFailedClosure unforward_closure;
young_gen->object_iterate(&unforward_closure); young_gen->object_iterate(&unforward_closure);
if (PrintGC && Verbose) { log_trace(gc, ergo)("Restoring " SIZE_FORMAT " marks", _preserved_oop_stack.size());
gclog_or_tty->print_cr("Restoring " SIZE_FORMAT " marks", _preserved_oop_stack.size());
}
// Restore any saved marks. // Restore any saved marks.
while (!_preserved_oop_stack.is_empty()) { while (!_preserved_oop_stack.is_empty()) {
@ -772,19 +737,12 @@ bool PSScavenge::should_attempt_scavenge() {
size_t promotion_estimate = MIN2(avg_promoted, young_gen->used_in_bytes()); size_t promotion_estimate = MIN2(avg_promoted, young_gen->used_in_bytes());
bool result = promotion_estimate < old_gen->free_in_bytes(); bool result = promotion_estimate < old_gen->free_in_bytes();
if (PrintGCDetails && Verbose) { log_trace(ergo)("%s scavenge: average_promoted " SIZE_FORMAT " padded_average_promoted " SIZE_FORMAT " free in old gen " SIZE_FORMAT,
gclog_or_tty->print(result ? " do scavenge: " : " skip scavenge: "); result ? "Do" : "Skip", (size_t) policy->average_promoted_in_bytes(),
gclog_or_tty->print_cr(" average_promoted " SIZE_FORMAT (size_t) policy->padded_average_promoted_in_bytes(),
" padded_average_promoted " SIZE_FORMAT old_gen->free_in_bytes());
" free in old gen " SIZE_FORMAT, if (young_gen->used_in_bytes() < (size_t) policy->padded_average_promoted_in_bytes()) {
(size_t) policy->average_promoted_in_bytes(), log_trace(ergo)(" padded_promoted_average is greater than maximum promotion = " SIZE_FORMAT, young_gen->used_in_bytes());
(size_t) policy->padded_average_promoted_in_bytes(),
old_gen->free_in_bytes());
if (young_gen->used_in_bytes() <
(size_t) policy->padded_average_promoted_in_bytes()) {
gclog_or_tty->print_cr(" padded_promoted_average is greater"
" than maximum promotion = " SIZE_FORMAT, young_gen->used_in_bytes());
}
} }
if (result) { if (result) {

View file

@ -29,6 +29,7 @@
#include "gc/parallel/parallelScavengeHeap.hpp" #include "gc/parallel/parallelScavengeHeap.hpp"
#include "gc/parallel/psPromotionManager.inline.hpp" #include "gc/parallel/psPromotionManager.inline.hpp"
#include "gc/parallel/psScavenge.hpp" #include "gc/parallel/psScavenge.hpp"
#include "logging/log.hpp"
#include "memory/iterator.hpp" #include "memory/iterator.hpp"
#include "utilities/globalDefinitions.hpp" #include "utilities/globalDefinitions.hpp"
@ -138,13 +139,11 @@ class PSScavengeKlassClosure: public KlassClosure {
// If the klass has not been dirtied we know that there's // If the klass has not been dirtied we know that there's
// no references into the young gen and we can skip it. // no references into the young gen and we can skip it.
if (TraceScavenge) { NOT_PRODUCT(ResourceMark rm);
ResourceMark rm; log_develop_trace(gc, scavenge)("PSScavengeKlassClosure::do_klass " PTR_FORMAT ", %s, dirty: %s",
gclog_or_tty->print_cr("PSScavengeKlassClosure::do_klass " PTR_FORMAT ", %s, dirty: %s", p2i(klass),
p2i(klass), klass->external_name(),
klass->external_name(), klass->has_modified_oops() ? "true" : "false");
klass->has_modified_oops() ? "true" : "false");
}
if (klass->has_modified_oops()) { if (klass->has_modified_oops()) {
// Clean the klass since we're going to scavenge all the metadata. // Clean the klass since we're going to scavenge all the metadata.

View file

@ -213,20 +213,6 @@ void PSVirtualSpace::verify() const {
} }
} }
void PSVirtualSpace::print() const {
gclog_or_tty->print_cr("virtual space [" PTR_FORMAT "]: alignment="
SIZE_FORMAT "K grows %s%s",
p2i(this), alignment() / K, grows_up() ? "up" : "down",
special() ? " (pinned in memory)" : "");
gclog_or_tty->print_cr(" reserved=" SIZE_FORMAT "K"
" [" PTR_FORMAT "," PTR_FORMAT "]"
" committed=" SIZE_FORMAT "K"
" [" PTR_FORMAT "," PTR_FORMAT "]",
reserved_size() / K,
p2i(reserved_low_addr()), p2i(reserved_high_addr()),
committed_size() / K,
p2i(committed_low_addr()), p2i(committed_high_addr()));
}
#endif // #ifndef PRODUCT #endif // #ifndef PRODUCT
void PSVirtualSpace::print_space_boundaries_on(outputStream* st) const { void PSVirtualSpace::print_space_boundaries_on(outputStream* st) const {

View file

@ -96,7 +96,6 @@ class PSVirtualSpace : public CHeapObj<mtGC> {
bool is_aligned(size_t val) const; bool is_aligned(size_t val) const;
bool is_aligned(char* val) const; bool is_aligned(char* val) const;
void verify() const; void verify() const;
void print() const;
virtual bool grows_up() const { return true; } virtual bool grows_up() const { return true; }
bool grows_down() const { return !grows_up(); } bool grows_down() const { return !grows_up(); }

View file

@ -30,6 +30,7 @@
#include "gc/parallel/psYoungGen.hpp" #include "gc/parallel/psYoungGen.hpp"
#include "gc/shared/gcUtil.hpp" #include "gc/shared/gcUtil.hpp"
#include "gc/shared/spaceDecorator.hpp" #include "gc/shared/spaceDecorator.hpp"
#include "logging/log.hpp"
#include "oops/oop.inline.hpp" #include "oops/oop.inline.hpp"
#include "runtime/java.hpp" #include "runtime/java.hpp"
@ -268,14 +269,12 @@ void PSYoungGen::resize(size_t eden_size, size_t survivor_size) {
space_invariants(); space_invariants();
if (PrintAdaptiveSizePolicy && Verbose) { log_trace(gc, ergo)("Young generation size: "
gclog_or_tty->print_cr("Young generation size: " "desired eden: " SIZE_FORMAT " survivor: " SIZE_FORMAT
"desired eden: " SIZE_FORMAT " survivor: " SIZE_FORMAT " used: " SIZE_FORMAT " capacity: " SIZE_FORMAT
" used: " SIZE_FORMAT " capacity: " SIZE_FORMAT " gen limits: " SIZE_FORMAT " / " SIZE_FORMAT,
" gen limits: " SIZE_FORMAT " / " SIZE_FORMAT, eden_size, survivor_size, used_in_bytes(), capacity_in_bytes(),
eden_size, survivor_size, used_in_bytes(), capacity_in_bytes(), _max_gen_size, min_gen_size());
_max_gen_size, min_gen_size());
}
} }
} }
@ -330,26 +329,17 @@ bool PSYoungGen::resize_generation(size_t eden_size, size_t survivor_size) {
size_changed = true; size_changed = true;
} }
} else { } else {
if (Verbose && PrintGC) { if (orig_size == gen_size_limit()) {
if (orig_size == gen_size_limit()) { log_trace(gc)("PSYoung generation size at maximum: " SIZE_FORMAT "K", orig_size/K);
gclog_or_tty->print_cr("PSYoung generation size at maximum: " } else if (orig_size == min_gen_size()) {
SIZE_FORMAT "K", orig_size/K); log_trace(gc)("PSYoung generation size at minium: " SIZE_FORMAT "K", orig_size/K);
} else if (orig_size == min_gen_size()) {
gclog_or_tty->print_cr("PSYoung generation size at minium: "
SIZE_FORMAT "K", orig_size/K);
}
} }
} }
if (size_changed) { if (size_changed) {
post_resize(); post_resize();
log_trace(gc)("PSYoung generation size changed: " SIZE_FORMAT "K->" SIZE_FORMAT "K",
if (Verbose && PrintGC) { orig_size/K, virtual_space()->committed_size()/K);
size_t current_size = virtual_space()->committed_size();
gclog_or_tty->print_cr("PSYoung generation size changed: "
SIZE_FORMAT "K->" SIZE_FORMAT "K",
orig_size/K, current_size/K);
}
} }
guarantee(eden_plus_survivors <= virtual_space()->committed_size() || guarantee(eden_plus_survivors <= virtual_space()->committed_size() ||
@ -412,28 +402,25 @@ void PSYoungGen::mangle_survivors(MutableSpace* s1,
s2->mangle_region(delta2_right); s2->mangle_region(delta2_right);
} }
if (TraceZapUnusedHeapArea) { // s1
// s1 log_develop_trace(gc)("Current region: [" PTR_FORMAT ", " PTR_FORMAT ") "
gclog_or_tty->print_cr("Current region: [" PTR_FORMAT ", " PTR_FORMAT ") " "New region: [" PTR_FORMAT ", " PTR_FORMAT ")",
"New region: [" PTR_FORMAT ", " PTR_FORMAT ")", p2i(s1->bottom()), p2i(s1->end()),
p2i(s1->bottom()), p2i(s1->end()), p2i(s1MR.start()), p2i(s1MR.end()));
p2i(s1MR.start()), p2i(s1MR.end())); log_develop_trace(gc)(" Mangle before: [" PTR_FORMAT ", "
gclog_or_tty->print_cr(" Mangle before: [" PTR_FORMAT ", " PTR_FORMAT ") Mangle after: [" PTR_FORMAT ", " PTR_FORMAT ")",
PTR_FORMAT ") Mangle after: [" PTR_FORMAT ", " PTR_FORMAT ")", p2i(delta1_left.start()), p2i(delta1_left.end()),
p2i(delta1_left.start()), p2i(delta1_left.end()), p2i(delta1_right.start()), p2i(delta1_right.end()));
p2i(delta1_right.start()), p2i(delta1_right.end()));
// s2
gclog_or_tty->print_cr("Current region: [" PTR_FORMAT ", " PTR_FORMAT ") "
"New region: [" PTR_FORMAT ", " PTR_FORMAT ")",
p2i(s2->bottom()), p2i(s2->end()),
p2i(s2MR.start()), p2i(s2MR.end()));
gclog_or_tty->print_cr(" Mangle before: [" PTR_FORMAT ", "
PTR_FORMAT ") Mangle after: [" PTR_FORMAT ", " PTR_FORMAT ")",
p2i(delta2_left.start()), p2i(delta2_left.end()),
p2i(delta2_right.start()), p2i(delta2_right.end()));
}
// s2
log_develop_trace(gc)("Current region: [" PTR_FORMAT ", " PTR_FORMAT ") "
"New region: [" PTR_FORMAT ", " PTR_FORMAT ")",
p2i(s2->bottom()), p2i(s2->end()),
p2i(s2MR.start()), p2i(s2MR.end()));
log_develop_trace(gc)(" Mangle before: [" PTR_FORMAT ", "
PTR_FORMAT ") Mangle after: [" PTR_FORMAT ", " PTR_FORMAT ")",
p2i(delta2_left.start()), p2i(delta2_left.end()),
p2i(delta2_right.start()), p2i(delta2_right.end()));
} }
#endif // NOT PRODUCT #endif // NOT PRODUCT
@ -448,41 +435,32 @@ void PSYoungGen::resize_spaces(size_t requested_eden_size,
return; return;
} }
if (PrintAdaptiveSizePolicy && Verbose) { log_trace(gc, ergo)("PSYoungGen::resize_spaces(requested_eden_size: " SIZE_FORMAT ", requested_survivor_size: " SIZE_FORMAT ")",
gclog_or_tty->print_cr("PSYoungGen::resize_spaces(requested_eden_size: " requested_eden_size, requested_survivor_size);
SIZE_FORMAT log_trace(gc, ergo)(" eden: [" PTR_FORMAT ".." PTR_FORMAT ") " SIZE_FORMAT,
", requested_survivor_size: " SIZE_FORMAT ")", p2i(eden_space()->bottom()),
requested_eden_size, requested_survivor_size); p2i(eden_space()->end()),
gclog_or_tty->print_cr(" eden: [" PTR_FORMAT ".." PTR_FORMAT ") " pointer_delta(eden_space()->end(),
SIZE_FORMAT, eden_space()->bottom(),
p2i(eden_space()->bottom()), sizeof(char)));
p2i(eden_space()->end()), log_trace(gc, ergo)(" from: [" PTR_FORMAT ".." PTR_FORMAT ") " SIZE_FORMAT,
pointer_delta(eden_space()->end(), p2i(from_space()->bottom()),
eden_space()->bottom(), p2i(from_space()->end()),
sizeof(char))); pointer_delta(from_space()->end(),
gclog_or_tty->print_cr(" from: [" PTR_FORMAT ".." PTR_FORMAT ") " from_space()->bottom(),
SIZE_FORMAT, sizeof(char)));
p2i(from_space()->bottom()), log_trace(gc, ergo)(" to: [" PTR_FORMAT ".." PTR_FORMAT ") " SIZE_FORMAT,
p2i(from_space()->end()), p2i(to_space()->bottom()),
pointer_delta(from_space()->end(), p2i(to_space()->end()),
from_space()->bottom(), pointer_delta( to_space()->end(),
sizeof(char))); to_space()->bottom(),
gclog_or_tty->print_cr(" to: [" PTR_FORMAT ".." PTR_FORMAT ") " sizeof(char)));
SIZE_FORMAT,
p2i(to_space()->bottom()),
p2i(to_space()->end()),
pointer_delta( to_space()->end(),
to_space()->bottom(),
sizeof(char)));
}
// There's nothing to do if the new sizes are the same as the current // There's nothing to do if the new sizes are the same as the current
if (requested_survivor_size == to_space()->capacity_in_bytes() && if (requested_survivor_size == to_space()->capacity_in_bytes() &&
requested_survivor_size == from_space()->capacity_in_bytes() && requested_survivor_size == from_space()->capacity_in_bytes() &&
requested_eden_size == eden_space()->capacity_in_bytes()) { requested_eden_size == eden_space()->capacity_in_bytes()) {
if (PrintAdaptiveSizePolicy && Verbose) { log_trace(gc, ergo)(" capacities are the right sizes, returning");
gclog_or_tty->print_cr(" capacities are the right sizes, returning");
}
return; return;
} }
@ -503,9 +481,7 @@ void PSYoungGen::resize_spaces(size_t requested_eden_size,
if (eden_from_to_order) { if (eden_from_to_order) {
// Eden, from, to // Eden, from, to
eden_from_to_order = true; eden_from_to_order = true;
if (PrintAdaptiveSizePolicy && Verbose) { log_trace(gc, ergo)(" Eden, from, to:");
gclog_or_tty->print_cr(" Eden, from, to:");
}
// Set eden // Set eden
// "requested_eden_size" is a goal for the size of eden // "requested_eden_size" is a goal for the size of eden
@ -566,28 +542,21 @@ void PSYoungGen::resize_spaces(size_t requested_eden_size,
guarantee(to_start != to_end, "to space is zero sized"); guarantee(to_start != to_end, "to space is zero sized");
if (PrintAdaptiveSizePolicy && Verbose) { log_trace(gc, ergo)(" [eden_start .. eden_end): [" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
gclog_or_tty->print_cr(" [eden_start .. eden_end): " p2i(eden_start),
"[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, p2i(eden_end),
p2i(eden_start), pointer_delta(eden_end, eden_start, sizeof(char)));
p2i(eden_end), log_trace(gc, ergo)(" [from_start .. from_end): [" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
pointer_delta(eden_end, eden_start, sizeof(char))); p2i(from_start),
gclog_or_tty->print_cr(" [from_start .. from_end): " p2i(from_end),
"[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, pointer_delta(from_end, from_start, sizeof(char)));
p2i(from_start), log_trace(gc, ergo)(" [ to_start .. to_end): [" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
p2i(from_end), p2i(to_start),
pointer_delta(from_end, from_start, sizeof(char))); p2i(to_end),
gclog_or_tty->print_cr(" [ to_start .. to_end): " pointer_delta( to_end, to_start, sizeof(char)));
"[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
p2i(to_start),
p2i(to_end),
pointer_delta( to_end, to_start, sizeof(char)));
}
} else { } else {
// Eden, to, from // Eden, to, from
if (PrintAdaptiveSizePolicy && Verbose) { log_trace(gc, ergo)(" Eden, to, from:");
gclog_or_tty->print_cr(" Eden, to, from:");
}
// To space gets priority over eden resizing. Note that we position // To space gets priority over eden resizing. Note that we position
// to space as if we were able to resize from space, even though from // to space as if we were able to resize from space, even though from
@ -623,23 +592,18 @@ void PSYoungGen::resize_spaces(size_t requested_eden_size,
eden_end = MAX2(eden_end, eden_start + alignment); eden_end = MAX2(eden_end, eden_start + alignment);
to_start = MAX2(to_start, eden_end); to_start = MAX2(to_start, eden_end);
if (PrintAdaptiveSizePolicy && Verbose) { log_trace(gc, ergo)(" [eden_start .. eden_end): [" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
gclog_or_tty->print_cr(" [eden_start .. eden_end): " p2i(eden_start),
"[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, p2i(eden_end),
p2i(eden_start), pointer_delta(eden_end, eden_start, sizeof(char)));
p2i(eden_end), log_trace(gc, ergo)(" [ to_start .. to_end): [" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
pointer_delta(eden_end, eden_start, sizeof(char))); p2i(to_start),
gclog_or_tty->print_cr(" [ to_start .. to_end): " p2i(to_end),
"[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, pointer_delta( to_end, to_start, sizeof(char)));
p2i(to_start), log_trace(gc, ergo)(" [from_start .. from_end): [" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
p2i(to_end), p2i(from_start),
pointer_delta( to_end, to_start, sizeof(char))); p2i(from_end),
gclog_or_tty->print_cr(" [from_start .. from_end): " pointer_delta(from_end, from_start, sizeof(char)));
"[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT,
p2i(from_start),
p2i(from_end),
pointer_delta(from_end, from_start, sizeof(char)));
}
} }
@ -658,7 +622,7 @@ void PSYoungGen::resize_spaces(size_t requested_eden_size,
// Let's make sure the call to initialize doesn't reset "top"! // Let's make sure the call to initialize doesn't reset "top"!
HeapWord* old_from_top = from_space()->top(); HeapWord* old_from_top = from_space()->top();
// For PrintAdaptiveSizePolicy block below // For logging block below
size_t old_from = from_space()->capacity_in_bytes(); size_t old_from = from_space()->capacity_in_bytes();
size_t old_to = to_space()->capacity_in_bytes(); size_t old_to = to_space()->capacity_in_bytes();
@ -704,18 +668,11 @@ void PSYoungGen::resize_spaces(size_t requested_eden_size,
assert(from_space()->top() == old_from_top, "from top changed!"); assert(from_space()->top() == old_from_top, "from top changed!");
if (PrintAdaptiveSizePolicy) { log_trace(gc, ergo)("AdaptiveSizePolicy::survivor space sizes: collection: %d (" SIZE_FORMAT ", " SIZE_FORMAT ") -> (" SIZE_FORMAT ", " SIZE_FORMAT ") ",
ParallelScavengeHeap* heap = ParallelScavengeHeap::heap(); ParallelScavengeHeap::heap()->total_collections(),
gclog_or_tty->print("AdaptiveSizePolicy::survivor space sizes: " old_from, old_to,
"collection: %d " from_space()->capacity_in_bytes(),
"(" SIZE_FORMAT ", " SIZE_FORMAT ") -> " to_space()->capacity_in_bytes());
"(" SIZE_FORMAT ", " SIZE_FORMAT ") ",
heap->total_collections(),
old_from, old_to,
from_space()->capacity_in_bytes(),
to_space()->capacity_in_bytes());
gclog_or_tty->cr();
}
} }
void PSYoungGen::swap_spaces() { void PSYoungGen::swap_spaces() {
@ -794,13 +751,8 @@ void PSYoungGen::compact() {
void PSYoungGen::print() const { print_on(tty); } void PSYoungGen::print() const { print_on(tty); }
void PSYoungGen::print_on(outputStream* st) const { void PSYoungGen::print_on(outputStream* st) const {
st->print(" %-15s", "PSYoungGen"); st->print(" %-15s", "PSYoungGen");
if (PrintGCDetails && Verbose) { st->print(" total " SIZE_FORMAT "K, used " SIZE_FORMAT "K",
st->print(" total " SIZE_FORMAT ", used " SIZE_FORMAT, capacity_in_bytes()/K, used_in_bytes()/K);
capacity_in_bytes(), used_in_bytes());
} else {
st->print(" total " SIZE_FORMAT "K, used " SIZE_FORMAT "K",
capacity_in_bytes()/K, used_in_bytes()/K);
}
virtual_space()->print_space_boundaries_on(st); virtual_space()->print_space_boundaries_on(st);
st->print(" eden"); eden_space()->print_on(st); st->print(" eden"); eden_space()->print_on(st);
st->print(" from"); from_space()->print_on(st); st->print(" from"); from_space()->print_on(st);
@ -809,13 +761,8 @@ void PSYoungGen::print_on(outputStream* st) const {
// Note that a space is not printed before the [NAME: // Note that a space is not printed before the [NAME:
void PSYoungGen::print_used_change(size_t prev_used) const { void PSYoungGen::print_used_change(size_t prev_used) const {
gclog_or_tty->print("[%s:", name()); log_info(gc, heap)("%s: " SIZE_FORMAT "K->" SIZE_FORMAT "K(" SIZE_FORMAT "K)",
gclog_or_tty->print(" " SIZE_FORMAT "K" name(), prev_used / K, used_in_bytes() / K, capacity_in_bytes() / K);
"->" SIZE_FORMAT "K"
"(" SIZE_FORMAT "K)",
prev_used / K, used_in_bytes() / K,
capacity_in_bytes() / K);
gclog_or_tty->print("]");
} }
size_t PSYoungGen::available_for_expansion() { size_t PSYoungGen::available_for_expansion() {

View file

@ -31,7 +31,7 @@
#include "gc/shared/gcPolicyCounters.hpp" #include "gc/shared/gcPolicyCounters.hpp"
#include "gc/shared/gcTimer.hpp" #include "gc/shared/gcTimer.hpp"
#include "gc/shared/gcTrace.hpp" #include "gc/shared/gcTrace.hpp"
#include "gc/shared/gcTraceTime.hpp" #include "gc/shared/gcTraceTime.inline.hpp"
#include "gc/shared/genCollectedHeap.hpp" #include "gc/shared/genCollectedHeap.hpp"
#include "gc/shared/genOopClosures.inline.hpp" #include "gc/shared/genOopClosures.inline.hpp"
#include "gc/shared/generationSpec.hpp" #include "gc/shared/generationSpec.hpp"
@ -39,6 +39,7 @@
#include "gc/shared/space.inline.hpp" #include "gc/shared/space.inline.hpp"
#include "gc/shared/spaceDecorator.hpp" #include "gc/shared/spaceDecorator.hpp"
#include "gc/shared/strongRootsScope.hpp" #include "gc/shared/strongRootsScope.hpp"
#include "logging/log.hpp"
#include "memory/iterator.hpp" #include "memory/iterator.hpp"
#include "oops/instanceRefKlass.hpp" #include "oops/instanceRefKlass.hpp"
#include "oops/oop.inline.hpp" #include "oops/oop.inline.hpp"
@ -134,13 +135,11 @@ void FastScanClosure::do_oop(oop* p) { FastScanClosure::do_oop_work(p); }
void FastScanClosure::do_oop(narrowOop* p) { FastScanClosure::do_oop_work(p); } void FastScanClosure::do_oop(narrowOop* p) { FastScanClosure::do_oop_work(p); }
void KlassScanClosure::do_klass(Klass* klass) { void KlassScanClosure::do_klass(Klass* klass) {
if (TraceScavenge) { NOT_PRODUCT(ResourceMark rm);
ResourceMark rm; log_develop_trace(gc, scavenge)("KlassScanClosure::do_klass " PTR_FORMAT ", %s, dirty: %s",
gclog_or_tty->print_cr("KlassScanClosure::do_klass " PTR_FORMAT ", %s, dirty: %s", p2i(klass),
p2i(klass), klass->external_name(),
klass->external_name(), klass->has_modified_oops() ? "true" : "false");
klass->has_modified_oops() ? "true" : "false");
}
// If the klass has not been dirtied we know that there's // If the klass has not been dirtied we know that there's
// no references into the young gen and we can skip it. // no references into the young gen and we can skip it.
@ -359,10 +358,7 @@ bool DefNewGeneration::expand(size_t bytes) {
// but the second succeeds and expands the heap to its maximum // but the second succeeds and expands the heap to its maximum
// value. // value.
if (GC_locker::is_active()) { if (GC_locker::is_active()) {
if (PrintGC && Verbose) { log_debug(gc)("Garbage collection disabled, expanded heap instead");
gclog_or_tty->print_cr("Garbage collection disabled, "
"expanded heap instead");
}
} }
return success; return success;
@ -429,22 +425,15 @@ void DefNewGeneration::compute_new_size() {
MemRegion cmr((HeapWord*)_virtual_space.low(), MemRegion cmr((HeapWord*)_virtual_space.low(),
(HeapWord*)_virtual_space.high()); (HeapWord*)_virtual_space.high());
gch->barrier_set()->resize_covered_region(cmr); gch->barrier_set()->resize_covered_region(cmr);
if (Verbose && PrintGC) {
size_t new_size_after = _virtual_space.committed_size(); log_debug(gc, heap, ergo)(
size_t eden_size_after = eden()->capacity(); "New generation size " SIZE_FORMAT "K->" SIZE_FORMAT "K [eden=" SIZE_FORMAT "K,survivor=" SIZE_FORMAT "K]",
size_t survivor_size_after = from()->capacity(); new_size_before/K, _virtual_space.committed_size()/K,
gclog_or_tty->print("New generation size " SIZE_FORMAT "K->" eden()->capacity()/K, from()->capacity()/K);
SIZE_FORMAT "K [eden=" log_trace(gc, heap, ergo)(
SIZE_FORMAT "K,survivor=" SIZE_FORMAT "K]", " [allowed " SIZE_FORMAT "K extra for %d threads]",
new_size_before/K, new_size_after/K,
eden_size_after/K, survivor_size_after/K);
if (WizardMode) {
gclog_or_tty->print("[allowed " SIZE_FORMAT "K extra for %d threads]",
thread_increase_size/K, threads_count); thread_increase_size/K, threads_count);
} }
gclog_or_tty->cr();
}
}
} }
void DefNewGeneration::younger_refs_iterate(OopsInGenClosure* cl, uint n_threads) { void DefNewGeneration::younger_refs_iterate(OopsInGenClosure* cl, uint n_threads) {
@ -507,34 +496,27 @@ void DefNewGeneration::space_iterate(SpaceClosure* blk,
// The last collection bailed out, we are running out of heap space, // The last collection bailed out, we are running out of heap space,
// so we try to allocate the from-space, too. // so we try to allocate the from-space, too.
HeapWord* DefNewGeneration::allocate_from_space(size_t size) { HeapWord* DefNewGeneration::allocate_from_space(size_t size) {
bool should_try_alloc = should_allocate_from_space() || GC_locker::is_active_and_needs_gc();
// If the Heap_lock is not locked by this thread, this will be called
// again later with the Heap_lock held.
bool do_alloc = should_try_alloc && (Heap_lock->owned_by_self() || (SafepointSynchronize::is_at_safepoint() && Thread::current()->is_VM_thread()));
HeapWord* result = NULL; HeapWord* result = NULL;
if (Verbose && PrintGCDetails) { if (do_alloc) {
gclog_or_tty->print("DefNewGeneration::allocate_from_space(" SIZE_FORMAT "):" result = from()->allocate(size);
" will_fail: %s" }
" heap_lock: %s"
" free: " SIZE_FORMAT, log_trace(gc, alloc)("DefNewGeneration::allocate_from_space(" SIZE_FORMAT "): will_fail: %s heap_lock: %s free: " SIZE_FORMAT "%s%s returns %s",
size, size,
GenCollectedHeap::heap()->incremental_collection_will_fail(false /* don't consult_young */) ? GenCollectedHeap::heap()->incremental_collection_will_fail(false /* don't consult_young */) ?
"true" : "false", "true" : "false",
Heap_lock->is_locked() ? "locked" : "unlocked", Heap_lock->is_locked() ? "locked" : "unlocked",
from()->free()); from()->free(),
} should_try_alloc ? "" : " should_allocate_from_space: NOT",
if (should_allocate_from_space() || GC_locker::is_active_and_needs_gc()) { do_alloc ? " Heap_lock is not owned by self" : "",
if (Heap_lock->owned_by_self() || result == NULL ? "NULL" : "object");
(SafepointSynchronize::is_at_safepoint() &&
Thread::current()->is_VM_thread())) {
// If the Heap_lock is not locked by this thread, this will be called
// again later with the Heap_lock held.
result = from()->allocate(size);
} else if (PrintGC && Verbose) {
gclog_or_tty->print_cr(" Heap_lock is not owned by self");
}
} else if (PrintGC && Verbose) {
gclog_or_tty->print_cr(" should_allocate_from_space: NOT");
}
if (PrintGC && Verbose) {
gclog_or_tty->print_cr(" returns %s", result == NULL ? "NULL" : "object");
}
return result; return result;
} }
@ -570,9 +552,7 @@ void DefNewGeneration::collect(bool full,
// from this generation, pass on collection; let the next generation // from this generation, pass on collection; let the next generation
// do it. // do it.
if (!collection_attempt_is_safe()) { if (!collection_attempt_is_safe()) {
if (Verbose && PrintGCDetails) { log_trace(gc)(":: Collection attempt not safe ::");
gclog_or_tty->print(" :: Collection attempt not safe :: ");
}
gch->set_incremental_collection_failed(); // Slight lie: we did not even attempt one gch->set_incremental_collection_failed(); // Slight lie: we did not even attempt one
return; return;
} }
@ -580,9 +560,7 @@ void DefNewGeneration::collect(bool full,
init_assuming_no_promotion_failure(); init_assuming_no_promotion_failure();
GCTraceTime t1(GCCauseString("GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, NULL); GCTraceTime(Trace, gc) tm("DefNew", NULL, gch->gc_cause());
// Capture heap used before collection (for printing).
size_t gch_prev_used = gch->used();
gch->trace_heap_before_gc(&gc_tracer); gch->trace_heap_before_gc(&gc_tracer);
@ -677,9 +655,7 @@ void DefNewGeneration::collect(bool full,
_promo_failure_scan_stack.clear(true); // Clear cached segments. _promo_failure_scan_stack.clear(true); // Clear cached segments.
remove_forwarding_pointers(); remove_forwarding_pointers();
if (PrintGCDetails) { log_debug(gc)("Promotion failed");
gclog_or_tty->print(" (promotion failed) ");
}
// Add to-space to the list of space to compact // Add to-space to the list of space to compact
// when a promotion failure has occurred. In that // when a promotion failure has occurred. In that
// case there can be live objects in to-space // case there can be live objects in to-space
@ -696,9 +672,6 @@ void DefNewGeneration::collect(bool full,
// Reset the PromotionFailureALot counters. // Reset the PromotionFailureALot counters.
NOT_PRODUCT(gch->reset_promotion_should_fail();) NOT_PRODUCT(gch->reset_promotion_should_fail();)
} }
if (PrintGC && !PrintGCDetails) {
gch->print_heap_change(gch_prev_used);
}
// set new iteration safe limit for the survivor spaces // set new iteration safe limit for the survivor spaces
from()->set_concurrent_iteration_safe_limit(from()->top()); from()->set_concurrent_iteration_safe_limit(from()->top());
to()->set_concurrent_iteration_safe_limit(to()->top()); to()->set_concurrent_iteration_safe_limit(to()->top());
@ -760,10 +733,8 @@ void DefNewGeneration::preserve_mark_if_necessary(oop obj, markOop m) {
} }
void DefNewGeneration::handle_promotion_failure(oop old) { void DefNewGeneration::handle_promotion_failure(oop old) {
if (PrintPromotionFailure && !_promotion_failed) { log_debug(gc, promotion)("Promotion failure size = %d) ", old->size());
gclog_or_tty->print(" (promotion failure size = %d) ",
old->size());
}
_promotion_failed = true; _promotion_failed = true;
_promotion_failed_info.register_copy_failure(old->size()); _promotion_failed_info.register_copy_failure(old->size());
preserve_mark_if_necessary(old, old->mark()); preserve_mark_if_necessary(old, old->mark());
@ -895,9 +866,7 @@ void DefNewGeneration::reset_scratch() {
bool DefNewGeneration::collection_attempt_is_safe() { bool DefNewGeneration::collection_attempt_is_safe() {
if (!to()->is_empty()) { if (!to()->is_empty()) {
if (Verbose && PrintGCDetails) { log_trace(gc)(":: to is not empty ::");
gclog_or_tty->print(" :: to is not empty :: ");
}
return false; return false;
} }
if (_old_gen == NULL) { if (_old_gen == NULL) {
@ -919,17 +888,13 @@ void DefNewGeneration::gc_epilogue(bool full) {
if (full) { if (full) {
DEBUG_ONLY(seen_incremental_collection_failed = false;) DEBUG_ONLY(seen_incremental_collection_failed = false;)
if (!collection_attempt_is_safe() && !_eden_space->is_empty()) { if (!collection_attempt_is_safe() && !_eden_space->is_empty()) {
if (Verbose && PrintGCDetails) { log_trace(gc)("DefNewEpilogue: cause(%s), full, not safe, set_failed, set_alloc_from, clear_seen",
gclog_or_tty->print("DefNewEpilogue: cause(%s), full, not safe, set_failed, set_alloc_from, clear_seen",
GCCause::to_string(gch->gc_cause())); GCCause::to_string(gch->gc_cause()));
}
gch->set_incremental_collection_failed(); // Slight lie: a full gc left us in that state gch->set_incremental_collection_failed(); // Slight lie: a full gc left us in that state
set_should_allocate_from_space(); // we seem to be running out of space set_should_allocate_from_space(); // we seem to be running out of space
} else { } else {
if (Verbose && PrintGCDetails) { log_trace(gc)("DefNewEpilogue: cause(%s), full, safe, clear_failed, clear_alloc_from, clear_seen",
gclog_or_tty->print("DefNewEpilogue: cause(%s), full, safe, clear_failed, clear_alloc_from, clear_seen",
GCCause::to_string(gch->gc_cause())); GCCause::to_string(gch->gc_cause()));
}
gch->clear_incremental_collection_failed(); // We just did a full collection gch->clear_incremental_collection_failed(); // We just did a full collection
clear_should_allocate_from_space(); // if set clear_should_allocate_from_space(); // if set
} }
@ -943,16 +908,12 @@ void DefNewGeneration::gc_epilogue(bool full) {
// a full collection in between. // a full collection in between.
if (!seen_incremental_collection_failed && if (!seen_incremental_collection_failed &&
gch->incremental_collection_failed()) { gch->incremental_collection_failed()) {
if (Verbose && PrintGCDetails) { log_trace(gc)("DefNewEpilogue: cause(%s), not full, not_seen_failed, failed, set_seen_failed",
gclog_or_tty->print("DefNewEpilogue: cause(%s), not full, not_seen_failed, failed, set_seen_failed",
GCCause::to_string(gch->gc_cause())); GCCause::to_string(gch->gc_cause()));
}
seen_incremental_collection_failed = true; seen_incremental_collection_failed = true;
} else if (seen_incremental_collection_failed) { } else if (seen_incremental_collection_failed) {
if (Verbose && PrintGCDetails) { log_trace(gc)("DefNewEpilogue: cause(%s), not full, seen_failed, will_clear_seen_failed",
gclog_or_tty->print("DefNewEpilogue: cause(%s), not full, seen_failed, will_clear_seen_failed",
GCCause::to_string(gch->gc_cause())); GCCause::to_string(gch->gc_cause()));
}
assert(gch->gc_cause() == GCCause::_scavenge_alot || assert(gch->gc_cause() == GCCause::_scavenge_alot ||
(GCCause::is_user_requested_gc(gch->gc_cause()) && UseConcMarkSweepGC && ExplicitGCInvokesConcurrent) || (GCCause::is_user_requested_gc(gch->gc_cause()) && UseConcMarkSweepGC && ExplicitGCInvokesConcurrent) ||
!gch->incremental_collection_failed(), !gch->incremental_collection_failed(),

View file

@ -339,7 +339,6 @@ protected:
virtual const char* name() const; virtual const char* name() const;
virtual const char* short_name() const { return "DefNew"; } virtual const char* short_name() const { return "DefNew"; }
// PrintHeapAtGC support.
void print_on(outputStream* st) const; void print_on(outputStream* st) const;
void verify(); void verify();

View file

@ -35,7 +35,7 @@
#include "gc/shared/gcHeapSummary.hpp" #include "gc/shared/gcHeapSummary.hpp"
#include "gc/shared/gcTimer.hpp" #include "gc/shared/gcTimer.hpp"
#include "gc/shared/gcTrace.hpp" #include "gc/shared/gcTrace.hpp"
#include "gc/shared/gcTraceTime.hpp" #include "gc/shared/gcTraceTime.inline.hpp"
#include "gc/shared/genCollectedHeap.hpp" #include "gc/shared/genCollectedHeap.hpp"
#include "gc/shared/generation.hpp" #include "gc/shared/generation.hpp"
#include "gc/shared/genOopClosures.inline.hpp" #include "gc/shared/genOopClosures.inline.hpp"
@ -71,8 +71,6 @@ void GenMarkSweep::invoke_at_safepoint(ReferenceProcessor* rp, bool clear_all_so
set_ref_processor(rp); set_ref_processor(rp);
rp->setup_policy(clear_all_softrefs); rp->setup_policy(clear_all_softrefs);
GCTraceTime t1(GCCauseString("Full GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, NULL);
gch->trace_heap_before_gc(_gc_tracer); gch->trace_heap_before_gc(_gc_tracer);
// When collecting the permanent generation Method*s may be moving, // When collecting the permanent generation Method*s may be moving,
@ -82,9 +80,6 @@ void GenMarkSweep::invoke_at_safepoint(ReferenceProcessor* rp, bool clear_all_so
// Increment the invocation count // Increment the invocation count
_total_invocations++; _total_invocations++;
// Capture heap size before collection for printing.
size_t gch_prev_used = gch->used();
// Capture used regions for each generation that will be // Capture used regions for each generation that will be
// subject to collection, so that card table adjustments can // subject to collection, so that card table adjustments can
// be made intelligently (see clear / invalidate further below). // be made intelligently (see clear / invalidate further below).
@ -134,10 +129,6 @@ void GenMarkSweep::invoke_at_safepoint(ReferenceProcessor* rp, bool clear_all_so
CodeCache::gc_epilogue(); CodeCache::gc_epilogue();
JvmtiExport::gc_epilogue(); JvmtiExport::gc_epilogue();
if (PrintGC && !PrintGCDetails) {
gch->print_heap_change(gch_prev_used);
}
// refs processing: clean slate // refs processing: clean slate
set_ref_processor(NULL); set_ref_processor(NULL);
@ -189,7 +180,7 @@ void GenMarkSweep::deallocate_stacks() {
void GenMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) { void GenMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
// Recursively traverse all live objects and mark them // Recursively traverse all live objects and mark them
GCTraceTime tm("phase 1", PrintGC && Verbose, true, _gc_timer); GCTraceTime(Trace, gc) tm("Phase 1: Mark live objects", _gc_timer);
GenCollectedHeap* gch = GenCollectedHeap::heap(); GenCollectedHeap* gch = GenCollectedHeap::heap();
@ -262,7 +253,7 @@ void GenMarkSweep::mark_sweep_phase2() {
GenCollectedHeap* gch = GenCollectedHeap::heap(); GenCollectedHeap* gch = GenCollectedHeap::heap();
GCTraceTime tm("phase 2", PrintGC && Verbose, true, _gc_timer); GCTraceTime(Trace, gc) tm("Phase 2: Compute new object addresses", _gc_timer);
gch->prepare_for_compaction(); gch->prepare_for_compaction();
} }
@ -278,7 +269,7 @@ void GenMarkSweep::mark_sweep_phase3() {
GenCollectedHeap* gch = GenCollectedHeap::heap(); GenCollectedHeap* gch = GenCollectedHeap::heap();
// Adjust the pointers to reflect the new locations // Adjust the pointers to reflect the new locations
GCTraceTime tm("phase 3", PrintGC && Verbose, true, _gc_timer); GCTraceTime(Trace, gc) tm("Phase 3: Adjust pointers", _gc_timer);
// Need new claim bits for the pointer adjustment tracing. // Need new claim bits for the pointer adjustment tracing.
ClassLoaderDataGraph::clear_claimed_marks(); ClassLoaderDataGraph::clear_claimed_marks();
@ -330,7 +321,7 @@ void GenMarkSweep::mark_sweep_phase4() {
// to use a higher index (saved from phase2) when verifying perm_gen. // to use a higher index (saved from phase2) when verifying perm_gen.
GenCollectedHeap* gch = GenCollectedHeap::heap(); GenCollectedHeap* gch = GenCollectedHeap::heap();
GCTraceTime tm("phase 4", PrintGC && Verbose, true, _gc_timer); GCTraceTime(Trace, gc) tm("Phase 4: Move objects", _gc_timer);
GenCompactClosure blk; GenCompactClosure blk;
gch->generation_iterate(&blk, true); gch->generation_iterate(&blk, true);

View file

@ -250,10 +250,7 @@ void MarkSweep::adjust_marks() {
void MarkSweep::restore_marks() { void MarkSweep::restore_marks() {
assert(_preserved_oop_stack.size() == _preserved_mark_stack.size(), assert(_preserved_oop_stack.size() == _preserved_mark_stack.size(),
"inconsistent preserved oop stacks"); "inconsistent preserved oop stacks");
if (PrintGC && Verbose) { log_trace(gc)("Restoring " SIZE_FORMAT " marks", _preserved_count + _preserved_oop_stack.size());
gclog_or_tty->print_cr("Restoring " SIZE_FORMAT " marks",
_preserved_count + _preserved_oop_stack.size());
}
// restore the marks we saved earlier // restore the marks we saved earlier
for (size_t i = 0; i < _preserved_count; i++) { for (size_t i = 0; i < _preserved_count; i++) {
@ -305,20 +302,13 @@ template <class T> static void trace_reference_gc(const char *s, oop obj,
T* referent_addr, T* referent_addr,
T* next_addr, T* next_addr,
T* discovered_addr) { T* discovered_addr) {
if(TraceReferenceGC && PrintGCDetails) { log_develop_trace(gc, ref)("%s obj " PTR_FORMAT, s, p2i(obj));
gclog_or_tty->print_cr("%s obj " PTR_FORMAT, s, p2i(obj)); log_develop_trace(gc, ref)(" referent_addr/* " PTR_FORMAT " / " PTR_FORMAT,
gclog_or_tty->print_cr(" referent_addr/* " PTR_FORMAT " / " p2i(referent_addr), p2i(referent_addr ? (address)oopDesc::load_decode_heap_oop(referent_addr) : NULL));
PTR_FORMAT, p2i(referent_addr), log_develop_trace(gc, ref)(" next_addr/* " PTR_FORMAT " / " PTR_FORMAT,
p2i(referent_addr ? p2i(next_addr), p2i(next_addr ? (address)oopDesc::load_decode_heap_oop(next_addr) : NULL));
(address)oopDesc::load_decode_heap_oop(referent_addr) : NULL)); log_develop_trace(gc, ref)(" discovered_addr/* " PTR_FORMAT " / " PTR_FORMAT,
gclog_or_tty->print_cr(" next_addr/* " PTR_FORMAT " / " p2i(discovered_addr), p2i(discovered_addr ? (address)oopDesc::load_decode_heap_oop(discovered_addr) : NULL));
PTR_FORMAT, p2i(next_addr),
p2i(next_addr ? (address)oopDesc::load_decode_heap_oop(next_addr) : NULL));
gclog_or_tty->print_cr(" discovered_addr/* " PTR_FORMAT " / "
PTR_FORMAT, p2i(discovered_addr),
p2i(discovered_addr ?
(address)oopDesc::load_decode_heap_oop(discovered_addr) : NULL));
}
} }
#endif #endif

View file

@ -32,6 +32,7 @@
#include "gc/shared/genOopClosures.inline.hpp" #include "gc/shared/genOopClosures.inline.hpp"
#include "gc/shared/generationSpec.hpp" #include "gc/shared/generationSpec.hpp"
#include "gc/shared/space.hpp" #include "gc/shared/space.hpp"
#include "logging/log.hpp"
#include "memory/allocation.inline.hpp" #include "memory/allocation.inline.hpp"
#include "oops/oop.inline.hpp" #include "oops/oop.inline.hpp"
#include "runtime/java.hpp" #include "runtime/java.hpp"
@ -81,42 +82,28 @@ bool TenuredGeneration::should_collect(bool full,
// why it returns what it returns (without re-evaluating the conditionals // why it returns what it returns (without re-evaluating the conditionals
// in case they aren't idempotent), so I'm doing it this way. // in case they aren't idempotent), so I'm doing it this way.
// DeMorgan says it's okay. // DeMorgan says it's okay.
bool result = false; if (full) {
if (!result && full) { log_trace(gc)("TenuredGeneration::should_collect: because full");
result = true; return true;
if (PrintGC && Verbose) {
gclog_or_tty->print_cr("TenuredGeneration::should_collect: because"
" full");
}
} }
if (!result && should_allocate(size, is_tlab)) { if (should_allocate(size, is_tlab)) {
result = true; log_trace(gc)("TenuredGeneration::should_collect: because should_allocate(" SIZE_FORMAT ")", size);
if (PrintGC && Verbose) { return true;
gclog_or_tty->print_cr("TenuredGeneration::should_collect: because"
" should_allocate(" SIZE_FORMAT ")",
size);
}
} }
// If we don't have very much free space. // If we don't have very much free space.
// XXX: 10000 should be a percentage of the capacity!!! // XXX: 10000 should be a percentage of the capacity!!!
if (!result && free() < 10000) { if (free() < 10000) {
result = true; log_trace(gc)("TenuredGeneration::should_collect: because free(): " SIZE_FORMAT, free());
if (PrintGC && Verbose) { return true;
gclog_or_tty->print_cr("TenuredGeneration::should_collect: because"
" free(): " SIZE_FORMAT,
free());
}
} }
// If we had to expand to accommodate promotions from the young generation // If we had to expand to accommodate promotions from the young generation
if (!result && _capacity_at_prologue < capacity()) { if (_capacity_at_prologue < capacity()) {
result = true; log_trace(gc)("TenuredGeneration::should_collect: because_capacity_at_prologue: " SIZE_FORMAT " < capacity(): " SIZE_FORMAT,
if (PrintGC && Verbose) { _capacity_at_prologue, capacity());
gclog_or_tty->print_cr("TenuredGeneration::should_collect: because" return true;
"_capacity_at_prologue: " SIZE_FORMAT " < capacity(): " SIZE_FORMAT,
_capacity_at_prologue, capacity());
}
} }
return result;
return false;
} }
void TenuredGeneration::compute_new_size() { void TenuredGeneration::compute_new_size() {
@ -165,13 +152,10 @@ bool TenuredGeneration::promotion_attempt_is_safe(size_t max_promotion_in_bytes)
size_t available = max_contiguous_available(); size_t available = max_contiguous_available();
size_t av_promo = (size_t)gc_stats()->avg_promoted()->padded_average(); size_t av_promo = (size_t)gc_stats()->avg_promoted()->padded_average();
bool res = (available >= av_promo) || (available >= max_promotion_in_bytes); bool res = (available >= av_promo) || (available >= max_promotion_in_bytes);
if (PrintGC && Verbose) {
gclog_or_tty->print_cr( log_trace(gc)("Tenured: promo attempt is%s safe: available(" SIZE_FORMAT ") %s av_promo(" SIZE_FORMAT "), max_promo(" SIZE_FORMAT ")",
"Tenured: promo attempt is%s safe: available(" SIZE_FORMAT ") %s av_promo(" SIZE_FORMAT ")," res? "":" not", available, res? ">=":"<", av_promo, max_promotion_in_bytes);
"max_promo(" SIZE_FORMAT ")",
res? "":" not", available, res? ">=":"<",
av_promo, max_promotion_in_bytes);
}
return res; return res;
} }

View file

@ -27,6 +27,7 @@
#include "gc/shared/collectorPolicy.hpp" #include "gc/shared/collectorPolicy.hpp"
#include "gc/shared/gcCause.hpp" #include "gc/shared/gcCause.hpp"
#include "gc/shared/workgroup.hpp" #include "gc/shared/workgroup.hpp"
#include "logging/log.hpp"
#include "runtime/timer.hpp" #include "runtime/timer.hpp"
#include "utilities/ostream.hpp" #include "utilities/ostream.hpp"
elapsedTimer AdaptiveSizePolicy::_minor_timer; elapsedTimer AdaptiveSizePolicy::_minor_timer;
@ -166,14 +167,12 @@ uint AdaptiveSizePolicy::calc_default_active_workers(uintx total_workers,
"Jiggled active workers too much"); "Jiggled active workers too much");
} }
if (TraceDynamicGCThreads) { log_trace(gc, task)("GCTaskManager::calc_default_active_workers() : "
gclog_or_tty->print_cr("GCTaskManager::calc_default_active_workers() : " "active_workers(): " UINTX_FORMAT " new_active_workers: " UINTX_FORMAT " "
"active_workers(): " UINTX_FORMAT " new_active_workers: " UINTX_FORMAT " " "prev_active_workers: " UINTX_FORMAT "\n"
"prev_active_workers: " UINTX_FORMAT "\n" " active_workers_by_JT: " UINTX_FORMAT " active_workers_by_heap_size: " UINTX_FORMAT,
" active_workers_by_JT: " UINTX_FORMAT " active_workers_by_heap_size: " UINTX_FORMAT, active_workers, new_active_workers, prev_active_workers,
active_workers, new_active_workers, prev_active_workers, active_workers_by_JT, active_workers_by_heap_size);
active_workers_by_JT, active_workers_by_heap_size);
}
assert(new_active_workers > 0, "Always need at least 1"); assert(new_active_workers > 0, "Always need at least 1");
return new_active_workers; return new_active_workers;
} }
@ -275,14 +274,10 @@ void AdaptiveSizePolicy::minor_collection_end(GCCause::Cause gc_cause) {
update_minor_pause_young_estimator(minor_pause_in_ms); update_minor_pause_young_estimator(minor_pause_in_ms);
update_minor_pause_old_estimator(minor_pause_in_ms); update_minor_pause_old_estimator(minor_pause_in_ms);
if (PrintAdaptiveSizePolicy && Verbose) { log_trace(gc, ergo)("AdaptiveSizePolicy::minor_collection_end: minor gc cost: %f average: %f",
gclog_or_tty->print("AdaptiveSizePolicy::minor_collection_end: " collection_cost, _avg_minor_gc_cost->average());
"minor gc cost: %f average: %f", collection_cost, log_trace(gc, ergo)(" minor pause: %f minor period %f",
_avg_minor_gc_cost->average()); minor_pause_in_ms, _latest_minor_mutator_interval_seconds * MILLIUNITS);
gclog_or_tty->print_cr(" minor pause: %f minor period %f",
minor_pause_in_ms,
_latest_minor_mutator_interval_seconds * MILLIUNITS);
}
// Calculate variable used to estimate collection cost vs. gen sizes // Calculate variable used to estimate collection cost vs. gen sizes
assert(collection_cost >= 0.0, "Expected to be non-negative"); assert(collection_cost >= 0.0, "Expected to be non-negative");
@ -388,13 +383,10 @@ double AdaptiveSizePolicy::decaying_gc_cost() const {
// Decay using the time-since-last-major-gc // Decay using the time-since-last-major-gc
decayed_major_gc_cost = decaying_major_gc_cost(); decayed_major_gc_cost = decaying_major_gc_cost();
if (PrintGCDetails && Verbose) { log_trace(gc, ergo)("decaying_gc_cost: major interval average: %f time since last major gc: %f",
gclog_or_tty->print_cr("\ndecaying_gc_cost: major interval average:" avg_major_interval, time_since_last_major_gc);
" %f time since last major gc: %f", log_trace(gc, ergo)(" major gc cost: %f decayed major gc cost: %f",
avg_major_interval, time_since_last_major_gc); major_gc_cost(), decayed_major_gc_cost);
gclog_or_tty->print_cr(" major gc cost: %f decayed major gc cost: %f",
major_gc_cost(), decayed_major_gc_cost);
}
} }
} }
double result = MIN2(1.0, decayed_major_gc_cost + minor_gc_cost()); double result = MIN2(1.0, decayed_major_gc_cost + minor_gc_cost());
@ -461,21 +453,17 @@ void AdaptiveSizePolicy::check_gc_overhead_limit(
promo_limit = MAX2(promo_limit, _promo_size); promo_limit = MAX2(promo_limit, _promo_size);
if (PrintAdaptiveSizePolicy && (Verbose || log_trace(gc, ergo)(
(free_in_old_gen < (size_t) mem_free_old_limit && "PSAdaptiveSizePolicy::check_gc_overhead_limit:"
free_in_eden < (size_t) mem_free_eden_limit))) { " promo_limit: " SIZE_FORMAT
gclog_or_tty->print_cr( " max_eden_size: " SIZE_FORMAT
"PSAdaptiveSizePolicy::check_gc_overhead_limit:" " total_free_limit: " SIZE_FORMAT
" promo_limit: " SIZE_FORMAT " max_old_gen_size: " SIZE_FORMAT
" max_eden_size: " SIZE_FORMAT " max_eden_size: " SIZE_FORMAT
" total_free_limit: " SIZE_FORMAT " mem_free_limit: " SIZE_FORMAT,
" max_old_gen_size: " SIZE_FORMAT promo_limit, max_eden_size, total_free_limit,
" max_eden_size: " SIZE_FORMAT max_old_gen_size, max_eden_size,
" mem_free_limit: " SIZE_FORMAT, (size_t) mem_free_limit);
promo_limit, max_eden_size, total_free_limit,
max_old_gen_size, max_eden_size,
(size_t) mem_free_limit);
}
bool print_gc_overhead_limit_would_be_exceeded = false; bool print_gc_overhead_limit_would_be_exceeded = false;
if (is_full_gc) { if (is_full_gc) {
@ -521,10 +509,7 @@ void AdaptiveSizePolicy::check_gc_overhead_limit(
bool near_limit = gc_overhead_limit_near(); bool near_limit = gc_overhead_limit_near();
if (near_limit) { if (near_limit) {
collector_policy->set_should_clear_all_soft_refs(true); collector_policy->set_should_clear_all_soft_refs(true);
if (PrintGCDetails && Verbose) { log_trace(gc, ergo)("Nearing GC overhead limit, will be clearing all SoftReference");
gclog_or_tty->print_cr(" Nearing GC overhead limit, "
"will be clearing all SoftReference");
}
} }
} }
} }
@ -540,26 +525,25 @@ void AdaptiveSizePolicy::check_gc_overhead_limit(
} }
} }
if (UseGCOverheadLimit && PrintGCDetails && Verbose) { if (UseGCOverheadLimit) {
if (gc_overhead_limit_exceeded()) { if (gc_overhead_limit_exceeded()) {
gclog_or_tty->print_cr(" GC is exceeding overhead limit " log_trace(gc, ergo)("GC is exceeding overhead limit of " UINTX_FORMAT "%%", GCTimeLimit);
"of " UINTX_FORMAT "%%", GCTimeLimit);
reset_gc_overhead_limit_count(); reset_gc_overhead_limit_count();
} else if (print_gc_overhead_limit_would_be_exceeded) { } else if (print_gc_overhead_limit_would_be_exceeded) {
assert(gc_overhead_limit_count() > 0, "Should not be printing"); assert(gc_overhead_limit_count() > 0, "Should not be printing");
gclog_or_tty->print_cr(" GC would exceed overhead limit " log_trace(gc, ergo)("GC would exceed overhead limit of " UINTX_FORMAT "%% %d consecutive time(s)",
"of " UINTX_FORMAT "%% %d consecutive time(s)", GCTimeLimit, gc_overhead_limit_count());
GCTimeLimit, gc_overhead_limit_count());
} }
} }
} }
// Printing // Printing
bool AdaptiveSizePolicy::print_adaptive_size_policy_on(outputStream* st) const { bool AdaptiveSizePolicy::print() const {
assert(UseAdaptiveSizePolicy, "UseAdaptiveSizePolicy need to be enabled.");
// Should only be used with adaptive size policy turned on. if (!log_is_enabled(Debug, gc, ergo)) {
// Otherwise, there may be variables that are undefined. return false;
if (!UseAdaptiveSizePolicy) return false; }
// Print goal for which action is needed. // Print goal for which action is needed.
char* action = NULL; char* action = NULL;
@ -627,41 +611,24 @@ bool AdaptiveSizePolicy::print_adaptive_size_policy_on(outputStream* st) const {
tenured_gen_action = shrink_msg; tenured_gen_action = shrink_msg;
} }
st->print_cr(" UseAdaptiveSizePolicy actions to meet %s", action); log_debug(gc, ergo)("UseAdaptiveSizePolicy actions to meet %s", action);
st->print_cr(" GC overhead (%%)"); log_debug(gc, ergo)(" GC overhead (%%)");
st->print_cr(" Young generation: %7.2f\t %s", log_debug(gc, ergo)(" Young generation: %7.2f\t %s",
100.0 * avg_minor_gc_cost()->average(), 100.0 * avg_minor_gc_cost()->average(), young_gen_action);
young_gen_action); log_debug(gc, ergo)(" Tenured generation: %7.2f\t %s",
st->print_cr(" Tenured generation: %7.2f\t %s", 100.0 * avg_major_gc_cost()->average(), tenured_gen_action);
100.0 * avg_major_gc_cost()->average(),
tenured_gen_action);
return true; return true;
} }
bool AdaptiveSizePolicy::print_adaptive_size_policy_on( void AdaptiveSizePolicy::print_tenuring_threshold( uint new_tenuring_threshold_arg) const {
outputStream* st,
uint tenuring_threshold_arg) const {
if (!AdaptiveSizePolicy::print_adaptive_size_policy_on(st)) {
return false;
}
// Tenuring threshold // Tenuring threshold
bool tenuring_threshold_changed = true;
if (decrement_tenuring_threshold_for_survivor_limit()) { if (decrement_tenuring_threshold_for_survivor_limit()) {
st->print(" Tenuring threshold: (attempted to decrease to avoid" log_debug(gc, ergo)("Tenuring threshold: (attempted to decrease to avoid survivor space overflow) = %u", new_tenuring_threshold_arg);
" survivor space overflow) = ");
} else if (decrement_tenuring_threshold_for_gc_cost()) { } else if (decrement_tenuring_threshold_for_gc_cost()) {
st->print(" Tenuring threshold: (attempted to decrease to balance" log_debug(gc, ergo)("Tenuring threshold: (attempted to decrease to balance GC costs) = %u", new_tenuring_threshold_arg);
" GC costs) = ");
} else if (increment_tenuring_threshold_for_gc_cost()) { } else if (increment_tenuring_threshold_for_gc_cost()) {
st->print(" Tenuring threshold: (attempted to increase to balance" log_debug(gc, ergo)("Tenuring threshold: (attempted to increase to balance GC costs) = %u", new_tenuring_threshold_arg);
" GC costs) = ");
} else { } else {
tenuring_threshold_changed = false;
assert(!tenuring_threshold_change(), "(no change was attempted)"); assert(!tenuring_threshold_change(), "(no change was attempted)");
} }
if (tenuring_threshold_changed) {
st->print_cr("%u", tenuring_threshold_arg);
}
return true;
} }

View file

@ -28,6 +28,7 @@
#include "gc/shared/collectedHeap.hpp" #include "gc/shared/collectedHeap.hpp"
#include "gc/shared/gcCause.hpp" #include "gc/shared/gcCause.hpp"
#include "gc/shared/gcUtil.hpp" #include "gc/shared/gcUtil.hpp"
#include "logging/log.hpp"
#include "memory/allocation.hpp" #include "memory/allocation.hpp"
#include "memory/universe.hpp" #include "memory/universe.hpp"
@ -500,9 +501,8 @@ class AdaptiveSizePolicy : public CHeapObj<mtGC> {
} }
// Printing support // Printing support
virtual bool print_adaptive_size_policy_on(outputStream* st) const; virtual bool print() const;
bool print_adaptive_size_policy_on(outputStream* st, void print_tenuring_threshold(uint new_tenuring_threshold) const;
uint tenuring_threshold) const;
}; };
// Class that can be used to print information about the // Class that can be used to print information about the
@ -510,46 +510,26 @@ class AdaptiveSizePolicy : public CHeapObj<mtGC> {
// AdaptiveSizePolicyOutputInterval. Only print information // AdaptiveSizePolicyOutputInterval. Only print information
// if an adaptive size policy is in use. // if an adaptive size policy is in use.
class AdaptiveSizePolicyOutput : StackObj { class AdaptiveSizePolicyOutput : StackObj {
AdaptiveSizePolicy* _size_policy; static bool enabled() {
bool _do_print; return UseParallelGC &&
bool print_test(uint count) {
// A count of zero is a special value that indicates that the
// interval test should be ignored. An interval is of zero is
// a special value that indicates that the interval test should
// always fail (never do the print based on the interval test).
return PrintGCDetails &&
UseAdaptiveSizePolicy && UseAdaptiveSizePolicy &&
UseParallelGC && log_is_enabled(Debug, gc, ergo);
(AdaptiveSizePolicyOutputInterval > 0) &&
((count == 0) ||
((count % AdaptiveSizePolicyOutputInterval) == 0));
} }
public: public:
// The special value of a zero count can be used to ignore static void print() {
// the count test. if (enabled()) {
AdaptiveSizePolicyOutput(uint count) { Universe::heap()->size_policy()->print();
if (UseAdaptiveSizePolicy && (AdaptiveSizePolicyOutputInterval > 0)) {
CollectedHeap* heap = Universe::heap();
_size_policy = heap->size_policy();
_do_print = print_test(count);
} else {
_size_policy = NULL;
_do_print = false;
} }
} }
AdaptiveSizePolicyOutput(AdaptiveSizePolicy* size_policy,
uint count) : static void print(AdaptiveSizePolicy* size_policy, uint count) {
_size_policy(size_policy) { bool do_print =
if (UseAdaptiveSizePolicy && (AdaptiveSizePolicyOutputInterval > 0)) { enabled() &&
_do_print = print_test(count); (AdaptiveSizePolicyOutputInterval > 0) &&
} else { (count % AdaptiveSizePolicyOutputInterval) == 0;
_do_print = false;
} if (do_print) {
} size_policy->print();
~AdaptiveSizePolicyOutput() {
if (_do_print) {
assert(UseAdaptiveSizePolicy, "Should not be in use");
_size_policy->print_adaptive_size_policy_on(gclog_or_tty);
} }
} }
}; };

View file

@ -28,6 +28,7 @@
#include "gc/shared/collectorPolicy.hpp" #include "gc/shared/collectorPolicy.hpp"
#include "gc/shared/gcPolicyCounters.hpp" #include "gc/shared/gcPolicyCounters.hpp"
#include "memory/resourceArea.hpp" #include "memory/resourceArea.hpp"
#include "logging/log.hpp"
#include "utilities/copy.hpp" #include "utilities/copy.hpp"
/* Copyright (c) 1992, 2015, Oracle and/or its affiliates, and Stanford University. /* Copyright (c) 1992, 2015, Oracle and/or its affiliates, and Stanford University.
@ -94,24 +95,18 @@ uint ageTable::compute_tenuring_threshold(size_t survivor_capacity, GCPolicyCoun
result = age < MaxTenuringThreshold ? age : MaxTenuringThreshold; result = age < MaxTenuringThreshold ? age : MaxTenuringThreshold;
} }
if (PrintTenuringDistribution || UsePerfData) {
if (PrintTenuringDistribution) { log_debug(gc, age)("Desired survivor size " SIZE_FORMAT " bytes, new threshold " UINTX_FORMAT " (max threshold " UINTX_FORMAT ")",
gclog_or_tty->cr(); desired_survivor_size*oopSize, (uintx) result, MaxTenuringThreshold);
gclog_or_tty->print_cr("Desired survivor size " SIZE_FORMAT " bytes, new threshold "
UINTX_FORMAT " (max threshold " UINTX_FORMAT ")",
desired_survivor_size*oopSize, (uintx) result, MaxTenuringThreshold);
}
if (log_is_enabled(Trace, gc, age) || UsePerfData) {
size_t total = 0; size_t total = 0;
uint age = 1; uint age = 1;
while (age < table_size) { while (age < table_size) {
total += sizes[age]; total += sizes[age];
if (sizes[age] > 0) { if (sizes[age] > 0) {
if (PrintTenuringDistribution) { log_trace(gc, age)("- age %3u: " SIZE_FORMAT_W(10) " bytes, " SIZE_FORMAT_W(10) " total",
gclog_or_tty->print_cr("- age %3u: " SIZE_FORMAT_W(10) " bytes, " SIZE_FORMAT_W(10) " total", age, sizes[age]*oopSize, total*oopSize);
age, sizes[age]*oopSize, total*oopSize);
}
} }
if (UsePerfData) { if (UsePerfData) {
_perf_sizes[age]->set_value(sizes[age]*oopSize); _perf_sizes[age]->set_value(sizes[age]*oopSize);

View file

@ -28,6 +28,7 @@
#include "gc/shared/space.inline.hpp" #include "gc/shared/space.inline.hpp"
#include "memory/iterator.hpp" #include "memory/iterator.hpp"
#include "memory/universe.hpp" #include "memory/universe.hpp"
#include "logging/log.hpp"
#include "oops/oop.inline.hpp" #include "oops/oop.inline.hpp"
#include "runtime/java.hpp" #include "runtime/java.hpp"
#include "services/memTracker.hpp" #include "services/memTracker.hpp"
@ -53,19 +54,11 @@ BlockOffsetSharedArray::BlockOffsetSharedArray(MemRegion reserved,
} }
_offset_array = (u_char*)_vs.low_boundary(); _offset_array = (u_char*)_vs.low_boundary();
resize(init_word_size); resize(init_word_size);
if (TraceBlockOffsetTable) { log_trace(gc, bot)("BlockOffsetSharedArray::BlockOffsetSharedArray: ");
gclog_or_tty->print_cr("BlockOffsetSharedArray::BlockOffsetSharedArray: "); log_trace(gc, bot)(" rs.base(): " INTPTR_FORMAT " rs.size(): " INTPTR_FORMAT " rs end(): " INTPTR_FORMAT,
gclog_or_tty->print_cr(" " p2i(rs.base()), rs.size(), p2i(rs.base() + rs.size()));
" rs.base(): " INTPTR_FORMAT log_trace(gc, bot)(" _vs.low_boundary(): " INTPTR_FORMAT " _vs.high_boundary(): " INTPTR_FORMAT,
" rs.size(): " INTPTR_FORMAT p2i(_vs.low_boundary()), p2i(_vs.high_boundary()));
" rs end(): " INTPTR_FORMAT,
p2i(rs.base()), rs.size(), p2i(rs.base() + rs.size()));
gclog_or_tty->print_cr(" "
" _vs.low_boundary(): " INTPTR_FORMAT
" _vs.high_boundary(): " INTPTR_FORMAT,
p2i(_vs.low_boundary()),
p2i(_vs.high_boundary()));
}
} }
void BlockOffsetSharedArray::resize(size_t new_word_size) { void BlockOffsetSharedArray::resize(size_t new_word_size) {

View file

@ -33,6 +33,7 @@
#include "gc/shared/space.inline.hpp" #include "gc/shared/space.inline.hpp"
#include "memory/iterator.hpp" #include "memory/iterator.hpp"
#include "memory/memRegion.hpp" #include "memory/memRegion.hpp"
#include "logging/log.hpp"
#include "runtime/java.hpp" #include "runtime/java.hpp"
CardGeneration::CardGeneration(ReservedSpace rs, CardGeneration::CardGeneration(ReservedSpace rs,
@ -96,13 +97,10 @@ bool CardGeneration::grow_by(size_t bytes) {
// update the space and generation capacity counters // update the space and generation capacity counters
update_counters(); update_counters();
if (Verbose && PrintGC) { size_t new_mem_size = _virtual_space.committed_size();
size_t new_mem_size = _virtual_space.committed_size(); size_t old_mem_size = new_mem_size - bytes;
size_t old_mem_size = new_mem_size - bytes; log_trace(gc, heap)("Expanding %s from " SIZE_FORMAT "K by " SIZE_FORMAT "K to " SIZE_FORMAT "K",
gclog_or_tty->print_cr("Expanding %s from " SIZE_FORMAT "K by " name(), old_mem_size/K, bytes/K, new_mem_size/K);
SIZE_FORMAT "K to " SIZE_FORMAT "K",
name(), old_mem_size/K, bytes/K, new_mem_size/K);
}
} }
return result; return result;
} }
@ -133,10 +131,8 @@ bool CardGeneration::expand(size_t bytes, size_t expand_bytes) {
if (!success) { if (!success) {
success = grow_to_reserved(); success = grow_to_reserved();
} }
if (PrintGC && Verbose) { if (success && GC_locker::is_active_and_needs_gc()) {
if (success && GC_locker::is_active_and_needs_gc()) { log_trace(gc, heap)("Garbage collection disabled, expanded heap instead");
gclog_or_tty->print_cr("Garbage collection disabled, expanded heap instead");
}
} }
return success; return success;
@ -172,12 +168,10 @@ void CardGeneration::shrink(size_t bytes) {
// Shrink the card table // Shrink the card table
GenCollectedHeap::heap()->barrier_set()->resize_covered_region(mr); GenCollectedHeap::heap()->barrier_set()->resize_covered_region(mr);
if (Verbose && PrintGC) { size_t new_mem_size = _virtual_space.committed_size();
size_t new_mem_size = _virtual_space.committed_size(); size_t old_mem_size = new_mem_size + size;
size_t old_mem_size = new_mem_size + size; log_trace(gc, heap)("Shrinking %s from " SIZE_FORMAT "K to " SIZE_FORMAT "K",
gclog_or_tty->print_cr("Shrinking %s from " SIZE_FORMAT "K to " SIZE_FORMAT "K", name(), old_mem_size/K, new_mem_size/K);
name(), old_mem_size/K, new_mem_size/K);
}
} }
// No young generation references, clear this generation's cards. // No young generation references, clear this generation's cards.
@ -211,26 +205,17 @@ void CardGeneration::compute_new_size() {
minimum_desired_capacity = MAX2(minimum_desired_capacity, initial_size()); minimum_desired_capacity = MAX2(minimum_desired_capacity, initial_size());
assert(used_after_gc <= minimum_desired_capacity, "sanity check"); assert(used_after_gc <= minimum_desired_capacity, "sanity check");
if (PrintGC && Verbose) {
const size_t free_after_gc = free(); const size_t free_after_gc = free();
const double free_percentage = ((double)free_after_gc) / capacity_after_gc; const double free_percentage = ((double)free_after_gc) / capacity_after_gc;
gclog_or_tty->print_cr("TenuredGeneration::compute_new_size: "); log_trace(gc, heap)("TenuredGeneration::compute_new_size:");
gclog_or_tty->print_cr(" " log_trace(gc, heap)(" minimum_free_percentage: %6.2f maximum_used_percentage: %6.2f",
" minimum_free_percentage: %6.2f"
" maximum_used_percentage: %6.2f",
minimum_free_percentage, minimum_free_percentage,
maximum_used_percentage); maximum_used_percentage);
gclog_or_tty->print_cr(" " log_trace(gc, heap)(" free_after_gc : %6.1fK used_after_gc : %6.1fK capacity_after_gc : %6.1fK",
" free_after_gc : %6.1fK"
" used_after_gc : %6.1fK"
" capacity_after_gc : %6.1fK",
free_after_gc / (double) K, free_after_gc / (double) K,
used_after_gc / (double) K, used_after_gc / (double) K,
capacity_after_gc / (double) K); capacity_after_gc / (double) K);
gclog_or_tty->print_cr(" " log_trace(gc, heap)(" free_percentage: %6.2f", free_percentage);
" free_percentage: %6.2f",
free_percentage);
}
if (capacity_after_gc < minimum_desired_capacity) { if (capacity_after_gc < minimum_desired_capacity) {
// If we have less free space than we want then expand // If we have less free space than we want then expand
@ -239,15 +224,10 @@ void CardGeneration::compute_new_size() {
if (expand_bytes >= _min_heap_delta_bytes) { if (expand_bytes >= _min_heap_delta_bytes) {
expand(expand_bytes, 0); // safe if expansion fails expand(expand_bytes, 0); // safe if expansion fails
} }
if (PrintGC && Verbose) { log_trace(gc, heap)(" expanding: minimum_desired_capacity: %6.1fK expand_bytes: %6.1fK _min_heap_delta_bytes: %6.1fK",
gclog_or_tty->print_cr(" expanding:" minimum_desired_capacity / (double) K,
" minimum_desired_capacity: %6.1fK" expand_bytes / (double) K,
" expand_bytes: %6.1fK" _min_heap_delta_bytes / (double) K);
" _min_heap_delta_bytes: %6.1fK",
minimum_desired_capacity / (double) K,
expand_bytes / (double) K,
_min_heap_delta_bytes / (double) K);
}
return; return;
} }
@ -262,20 +242,12 @@ void CardGeneration::compute_new_size() {
const double max_tmp = used_after_gc / minimum_used_percentage; const double max_tmp = used_after_gc / minimum_used_percentage;
size_t maximum_desired_capacity = (size_t)MIN2(max_tmp, double(max_uintx)); size_t maximum_desired_capacity = (size_t)MIN2(max_tmp, double(max_uintx));
maximum_desired_capacity = MAX2(maximum_desired_capacity, initial_size()); maximum_desired_capacity = MAX2(maximum_desired_capacity, initial_size());
if (PrintGC && Verbose) { log_trace(gc, heap)(" maximum_free_percentage: %6.2f minimum_used_percentage: %6.2f",
gclog_or_tty->print_cr(" " maximum_free_percentage, minimum_used_percentage);
" maximum_free_percentage: %6.2f" log_trace(gc, heap)(" _capacity_at_prologue: %6.1fK minimum_desired_capacity: %6.1fK maximum_desired_capacity: %6.1fK",
" minimum_used_percentage: %6.2f",
maximum_free_percentage,
minimum_used_percentage);
gclog_or_tty->print_cr(" "
" _capacity_at_prologue: %6.1fK"
" minimum_desired_capacity: %6.1fK"
" maximum_desired_capacity: %6.1fK",
_capacity_at_prologue / (double) K, _capacity_at_prologue / (double) K,
minimum_desired_capacity / (double) K, minimum_desired_capacity / (double) K,
maximum_desired_capacity / (double) K); maximum_desired_capacity / (double) K);
}
assert(minimum_desired_capacity <= maximum_desired_capacity, assert(minimum_desired_capacity <= maximum_desired_capacity,
"sanity check"); "sanity check");
@ -295,23 +267,13 @@ void CardGeneration::compute_new_size() {
} else { } else {
_shrink_factor = MIN2(current_shrink_factor * 4, (size_t) 100); _shrink_factor = MIN2(current_shrink_factor * 4, (size_t) 100);
} }
if (PrintGC && Verbose) { log_trace(gc, heap)(" shrinking: initSize: %.1fK maximum_desired_capacity: %.1fK",
gclog_or_tty->print_cr(" " initial_size() / (double) K, maximum_desired_capacity / (double) K);
" shrinking:" log_trace(gc, heap)(" shrink_bytes: %.1fK current_shrink_factor: " SIZE_FORMAT " new shrink factor: " SIZE_FORMAT " _min_heap_delta_bytes: %.1fK",
" initSize: %.1fK"
" maximum_desired_capacity: %.1fK",
initial_size() / (double) K,
maximum_desired_capacity / (double) K);
gclog_or_tty->print_cr(" "
" shrink_bytes: %.1fK"
" current_shrink_factor: " SIZE_FORMAT
" new shrink factor: " SIZE_FORMAT
" _min_heap_delta_bytes: %.1fK",
shrink_bytes / (double) K, shrink_bytes / (double) K,
current_shrink_factor, current_shrink_factor,
_shrink_factor, _shrink_factor,
_min_heap_delta_bytes / (double) K); _min_heap_delta_bytes / (double) K);
}
} }
} }
@ -324,18 +286,11 @@ void CardGeneration::compute_new_size() {
// We have two shrinking computations, take the largest // We have two shrinking computations, take the largest
shrink_bytes = MAX2(shrink_bytes, expansion_for_promotion); shrink_bytes = MAX2(shrink_bytes, expansion_for_promotion);
assert(shrink_bytes <= max_shrink_bytes, "invalid shrink size"); assert(shrink_bytes <= max_shrink_bytes, "invalid shrink size");
if (PrintGC && Verbose) { log_trace(gc, heap)(" aggressive shrinking: _capacity_at_prologue: %.1fK capacity_after_gc: %.1fK expansion_for_promotion: %.1fK shrink_bytes: %.1fK",
gclog_or_tty->print_cr(" " capacity_after_gc / (double) K,
" aggressive shrinking:" _capacity_at_prologue / (double) K,
" _capacity_at_prologue: %.1fK" expansion_for_promotion / (double) K,
" capacity_after_gc: %.1fK" shrink_bytes / (double) K);
" expansion_for_promotion: %.1fK"
" shrink_bytes: %.1fK",
capacity_after_gc / (double) K,
_capacity_at_prologue / (double) K,
expansion_for_promotion / (double) K,
shrink_bytes / (double) K);
}
} }
// Don't shrink unless it's significant // Don't shrink unless it's significant
if (shrink_bytes >= _min_heap_delta_bytes) { if (shrink_bytes >= _min_heap_delta_bytes) {

View file

@ -28,6 +28,7 @@
#include "gc/shared/genCollectedHeap.hpp" #include "gc/shared/genCollectedHeap.hpp"
#include "gc/shared/space.inline.hpp" #include "gc/shared/space.inline.hpp"
#include "memory/virtualspace.hpp" #include "memory/virtualspace.hpp"
#include "logging/log.hpp"
#include "services/memTracker.hpp" #include "services/memTracker.hpp"
#include "utilities/macros.hpp" #include "utilities/macros.hpp"
@ -115,17 +116,10 @@ void CardTableModRefBS::initialize() {
!ExecMem, "card table last card"); !ExecMem, "card table last card");
*guard_card = last_card; *guard_card = last_card;
if (TraceCardTableModRefBS) { log_trace(gc, barrier)("CardTableModRefBS::CardTableModRefBS: ");
gclog_or_tty->print_cr("CardTableModRefBS::CardTableModRefBS: "); log_trace(gc, barrier)(" &_byte_map[0]: " INTPTR_FORMAT " &_byte_map[_last_valid_index]: " INTPTR_FORMAT,
gclog_or_tty->print_cr(" " p2i(&_byte_map[0]), p2i(&_byte_map[_last_valid_index]));
" &_byte_map[0]: " INTPTR_FORMAT log_trace(gc, barrier)(" byte_map_base: " INTPTR_FORMAT, p2i(byte_map_base));
" &_byte_map[_last_valid_index]: " INTPTR_FORMAT,
p2i(&_byte_map[0]),
p2i(&_byte_map[_last_valid_index]));
gclog_or_tty->print_cr(" "
" byte_map_base: " INTPTR_FORMAT,
p2i(byte_map_base));
}
} }
CardTableModRefBS::~CardTableModRefBS() { CardTableModRefBS::~CardTableModRefBS() {
@ -350,29 +344,17 @@ void CardTableModRefBS::resize_covered_region(MemRegion new_region) {
} }
// In any case, the covered size changes. // In any case, the covered size changes.
_covered[ind].set_word_size(new_region.word_size()); _covered[ind].set_word_size(new_region.word_size());
if (TraceCardTableModRefBS) {
gclog_or_tty->print_cr("CardTableModRefBS::resize_covered_region: "); log_trace(gc, barrier)("CardTableModRefBS::resize_covered_region: ");
gclog_or_tty->print_cr(" " log_trace(gc, barrier)(" _covered[%d].start(): " INTPTR_FORMAT " _covered[%d].last(): " INTPTR_FORMAT,
" _covered[%d].start(): " INTPTR_FORMAT ind, p2i(_covered[ind].start()), ind, p2i(_covered[ind].last()));
" _covered[%d].last(): " INTPTR_FORMAT, log_trace(gc, barrier)(" _committed[%d].start(): " INTPTR_FORMAT " _committed[%d].last(): " INTPTR_FORMAT,
ind, p2i(_covered[ind].start()), ind, p2i(_committed[ind].start()), ind, p2i(_committed[ind].last()));
ind, p2i(_covered[ind].last())); log_trace(gc, barrier)(" byte_for(start): " INTPTR_FORMAT " byte_for(last): " INTPTR_FORMAT,
gclog_or_tty->print_cr(" " p2i(byte_for(_covered[ind].start())), p2i(byte_for(_covered[ind].last())));
" _committed[%d].start(): " INTPTR_FORMAT log_trace(gc, barrier)(" addr_for(start): " INTPTR_FORMAT " addr_for(last): " INTPTR_FORMAT,
" _committed[%d].last(): " INTPTR_FORMAT, p2i(addr_for((jbyte*) _committed[ind].start())), p2i(addr_for((jbyte*) _committed[ind].last())));
ind, p2i(_committed[ind].start()),
ind, p2i(_committed[ind].last()));
gclog_or_tty->print_cr(" "
" byte_for(start): " INTPTR_FORMAT
" byte_for(last): " INTPTR_FORMAT,
p2i(byte_for(_covered[ind].start())),
p2i(byte_for(_covered[ind].last())));
gclog_or_tty->print_cr(" "
" addr_for(start): " INTPTR_FORMAT
" addr_for(last): " INTPTR_FORMAT,
p2i(addr_for((jbyte*) _committed[ind].start())),
p2i(addr_for((jbyte*) _committed[ind].last())));
}
// Touch the last card of the covered region to show that it // Touch the last card of the covered region to show that it
// is committed (or SEGV). // is committed (or SEGV).
debug_only((void) (*byte_for(_covered[ind].last()));) debug_only((void) (*byte_for(_covered[ind].last()));)

View file

@ -30,9 +30,10 @@
#include "gc/shared/collectedHeap.inline.hpp" #include "gc/shared/collectedHeap.inline.hpp"
#include "gc/shared/gcHeapSummary.hpp" #include "gc/shared/gcHeapSummary.hpp"
#include "gc/shared/gcTrace.hpp" #include "gc/shared/gcTrace.hpp"
#include "gc/shared/gcTraceTime.hpp" #include "gc/shared/gcTraceTime.inline.hpp"
#include "gc/shared/gcWhen.hpp" #include "gc/shared/gcWhen.hpp"
#include "gc/shared/vmGCOperations.hpp" #include "gc/shared/vmGCOperations.hpp"
#include "logging/log.hpp"
#include "memory/metaspace.hpp" #include "memory/metaspace.hpp"
#include "oops/instanceMirrorKlass.hpp" #include "oops/instanceMirrorKlass.hpp"
#include "oops/oop.inline.hpp" #include "oops/oop.inline.hpp"
@ -53,7 +54,7 @@ void EventLogBase<GCMessage>::print(outputStream* st, GCMessage& m) {
st->print_raw(m); st->print_raw(m);
} }
void GCHeapLog::log_heap(bool before) { void GCHeapLog::log_heap(CollectedHeap* heap, bool before) {
if (!should_log()) { if (!should_log()) {
return; return;
} }
@ -65,11 +66,14 @@ void GCHeapLog::log_heap(bool before) {
_records[index].timestamp = timestamp; _records[index].timestamp = timestamp;
_records[index].data.is_before = before; _records[index].data.is_before = before;
stringStream st(_records[index].data.buffer(), _records[index].data.size()); stringStream st(_records[index].data.buffer(), _records[index].data.size());
if (before) {
Universe::print_heap_before_gc(&st, true); st.print_cr("{Heap %s GC invocations=%u (full %u):",
} else { before ? "before" : "after",
Universe::print_heap_after_gc(&st, true); heap->total_collections(),
} heap->total_full_collections());
heap->print_on(&st);
st.print_cr("}");
} }
VirtualSpaceSummary CollectedHeap::create_heap_space_summary() { VirtualSpaceSummary CollectedHeap::create_heap_space_summary() {
@ -108,20 +112,16 @@ MetaspaceSummary CollectedHeap::create_metaspace_summary() {
} }
void CollectedHeap::print_heap_before_gc() { void CollectedHeap::print_heap_before_gc() {
if (PrintHeapAtGC) { Universe::print_heap_before_gc();
Universe::print_heap_before_gc();
}
if (_gc_heap_log != NULL) { if (_gc_heap_log != NULL) {
_gc_heap_log->log_heap_before(); _gc_heap_log->log_heap_before(this);
} }
} }
void CollectedHeap::print_heap_after_gc() { void CollectedHeap::print_heap_after_gc() {
if (PrintHeapAtGC) { Universe::print_heap_after_gc();
Universe::print_heap_after_gc();
}
if (_gc_heap_log != NULL) { if (_gc_heap_log != NULL) {
_gc_heap_log->log_heap_after(); _gc_heap_log->log_heap_after(this);
} }
} }
@ -571,34 +571,30 @@ void CollectedHeap::resize_all_tlabs() {
} }
} }
void CollectedHeap::pre_full_gc_dump(GCTimer* timer) { void CollectedHeap::full_gc_dump(GCTimer* timer, const char* when) {
if (HeapDumpBeforeFullGC) { if (HeapDumpBeforeFullGC || HeapDumpAfterFullGC) {
GCIdMarkAndRestore gc_id_mark; GCIdMarkAndRestore gc_id_mark;
GCTraceTime tt("Heap Dump (before full gc): ", PrintGCDetails, false, timer); FormatBuffer<> title("Heap Dump (%s full gc)", when);
// We are doing a full collection and a heap dump before GCTraceTime(Info, gc) tm(title.buffer(), timer);
// full collection has been requested.
HeapDumper::dump_heap(); HeapDumper::dump_heap();
} }
if (PrintClassHistogramBeforeFullGC) { LogHandle(gc, classhisto) log;
if (log.is_trace()) {
ResourceMark rm;
GCIdMarkAndRestore gc_id_mark; GCIdMarkAndRestore gc_id_mark;
GCTraceTime tt("Class Histogram (before full gc): ", PrintGCDetails, true, timer); FormatBuffer<> title("Class Histogram (%s full gc)", when);
VM_GC_HeapInspection inspector(gclog_or_tty, false /* ! full gc */); GCTraceTime(Trace, gc, classhisto) tm(title.buffer(), timer);
VM_GC_HeapInspection inspector(log.trace_stream(), false /* ! full gc */);
inspector.doit(); inspector.doit();
} }
} }
void CollectedHeap::pre_full_gc_dump(GCTimer* timer) {
full_gc_dump(timer, "before");
}
void CollectedHeap::post_full_gc_dump(GCTimer* timer) { void CollectedHeap::post_full_gc_dump(GCTimer* timer) {
if (HeapDumpAfterFullGC) { full_gc_dump(timer, "after");
GCIdMarkAndRestore gc_id_mark;
GCTraceTime tt("Heap Dump (after full gc): ", PrintGCDetails, false, timer);
HeapDumper::dump_heap();
}
if (PrintClassHistogramAfterFullGC) {
GCIdMarkAndRestore gc_id_mark;
GCTraceTime tt("Class Histogram (after full gc): ", PrintGCDetails, true, timer);
VM_GC_HeapInspection inspector(gclog_or_tty, false /* ! full gc */);
inspector.doit();
}
} }
void CollectedHeap::initialize_reserved_region(HeapWord *start, HeapWord *end) { void CollectedHeap::initialize_reserved_region(HeapWord *start, HeapWord *end) {

View file

@ -58,18 +58,20 @@ class GCMessage : public FormatBuffer<1024> {
GCMessage() {} GCMessage() {}
}; };
class CollectedHeap;
class GCHeapLog : public EventLogBase<GCMessage> { class GCHeapLog : public EventLogBase<GCMessage> {
private: private:
void log_heap(bool before); void log_heap(CollectedHeap* heap, bool before);
public: public:
GCHeapLog() : EventLogBase<GCMessage>("GC Heap History") {} GCHeapLog() : EventLogBase<GCMessage>("GC Heap History") {}
void log_heap_before() { void log_heap_before(CollectedHeap* heap) {
log_heap(true); log_heap(heap, true);
} }
void log_heap_after() { void log_heap_after(CollectedHeap* heap) {
log_heap(false); log_heap(heap, false);
} }
}; };
@ -195,6 +197,8 @@ class CollectedHeap : public CHeapObj<mtInternal> {
virtual Name kind() const = 0; virtual Name kind() const = 0;
virtual const char* name() const = 0;
/** /**
* Returns JNI error code JNI_ENOMEM if memory could not be allocated, * Returns JNI error code JNI_ENOMEM if memory could not be allocated,
* and JNI_OK on success. * and JNI_OK on success.
@ -519,6 +523,9 @@ class CollectedHeap : public CHeapObj<mtInternal> {
virtual void prepare_for_verify() = 0; virtual void prepare_for_verify() = 0;
// Generate any dumps preceding or following a full gc // Generate any dumps preceding or following a full gc
private:
void full_gc_dump(GCTimer* timer, const char* when);
public:
void pre_full_gc_dump(GCTimer* timer); void pre_full_gc_dump(GCTimer* timer);
void post_full_gc_dump(GCTimer* timer); void post_full_gc_dump(GCTimer* timer);
@ -569,7 +576,7 @@ class CollectedHeap : public CHeapObj<mtInternal> {
void trace_heap_after_gc(const GCTracer* gc_tracer); void trace_heap_after_gc(const GCTracer* gc_tracer);
// Heap verification // Heap verification
virtual void verify(bool silent, VerifyOption option) = 0; virtual void verify(VerifyOption option) = 0;
// Non product verification and debugging. // Non product verification and debugging.
#ifndef PRODUCT #ifndef PRODUCT

View file

@ -32,6 +32,7 @@
#include "gc/shared/generationSpec.hpp" #include "gc/shared/generationSpec.hpp"
#include "gc/shared/space.hpp" #include "gc/shared/space.hpp"
#include "gc/shared/vmGCOperations.hpp" #include "gc/shared/vmGCOperations.hpp"
#include "logging/log.hpp"
#include "memory/universe.hpp" #include "memory/universe.hpp"
#include "runtime/arguments.hpp" #include "runtime/arguments.hpp"
#include "runtime/globals_extension.hpp" #include "runtime/globals_extension.hpp"
@ -137,11 +138,8 @@ void CollectorPolicy::initialize_flags() {
} }
void CollectorPolicy::initialize_size_info() { void CollectorPolicy::initialize_size_info() {
if (PrintGCDetails && Verbose) { log_debug(gc, heap)("Minimum heap " SIZE_FORMAT " Initial heap " SIZE_FORMAT " Maximum heap " SIZE_FORMAT,
gclog_or_tty->print_cr("Minimum heap " SIZE_FORMAT " Initial heap " _min_heap_byte_size, _initial_heap_byte_size, _max_heap_byte_size);
SIZE_FORMAT " Maximum heap " SIZE_FORMAT,
_min_heap_byte_size, _initial_heap_byte_size, _max_heap_byte_size);
}
DEBUG_ONLY(CollectorPolicy::assert_size_info();) DEBUG_ONLY(CollectorPolicy::assert_size_info();)
} }
@ -488,11 +486,8 @@ void GenCollectorPolicy::initialize_size_info() {
} }
} }
if (PrintGCDetails && Verbose) { log_trace(gc, heap)("1: Minimum young " SIZE_FORMAT " Initial young " SIZE_FORMAT " Maximum young " SIZE_FORMAT,
gclog_or_tty->print_cr("1: Minimum young " SIZE_FORMAT " Initial young " _min_young_size, _initial_young_size, _max_young_size);
SIZE_FORMAT " Maximum young " SIZE_FORMAT,
_min_young_size, _initial_young_size, _max_young_size);
}
// At this point the minimum, initial and maximum sizes // At this point the minimum, initial and maximum sizes
// of the overall heap and of the young generation have been determined. // of the overall heap and of the young generation have been determined.
@ -558,11 +553,8 @@ void GenCollectorPolicy::initialize_size_info() {
_initial_young_size = desired_young_size; _initial_young_size = desired_young_size;
} }
if (PrintGCDetails && Verbose) { log_trace(gc, heap)("2: Minimum young " SIZE_FORMAT " Initial young " SIZE_FORMAT " Maximum young " SIZE_FORMAT,
gclog_or_tty->print_cr("2: Minimum young " SIZE_FORMAT " Initial young " _min_young_size, _initial_young_size, _max_young_size);
SIZE_FORMAT " Maximum young " SIZE_FORMAT,
_min_young_size, _initial_young_size, _max_young_size);
}
} }
// Write back to flags if necessary. // Write back to flags if necessary.
@ -578,11 +570,8 @@ void GenCollectorPolicy::initialize_size_info() {
FLAG_SET_ERGO(size_t, OldSize, _initial_old_size); FLAG_SET_ERGO(size_t, OldSize, _initial_old_size);
} }
if (PrintGCDetails && Verbose) { log_trace(gc, heap)("Minimum old " SIZE_FORMAT " Initial old " SIZE_FORMAT " Maximum old " SIZE_FORMAT,
gclog_or_tty->print_cr("Minimum old " SIZE_FORMAT " Initial old " _min_old_size, _initial_old_size, _max_old_size);
SIZE_FORMAT " Maximum old " SIZE_FORMAT,
_min_old_size, _initial_old_size, _max_old_size);
}
DEBUG_ONLY(GenCollectorPolicy::assert_size_info();) DEBUG_ONLY(GenCollectorPolicy::assert_size_info();)
} }
@ -620,10 +609,7 @@ HeapWord* GenCollectorPolicy::mem_allocate_work(size_t size,
uint gc_count_before; // Read inside the Heap_lock locked region. uint gc_count_before; // Read inside the Heap_lock locked region.
{ {
MutexLocker ml(Heap_lock); MutexLocker ml(Heap_lock);
if (PrintGC && Verbose) { log_trace(gc, alloc)("GenCollectorPolicy::mem_allocate_work: attempting locked slow path allocation");
gclog_or_tty->print_cr("GenCollectorPolicy::mem_allocate_work:"
" attempting locked slow path allocation");
}
// Note that only large objects get a shot at being // Note that only large objects get a shot at being
// allocated in later generations. // allocated in later generations.
bool first_only = ! should_try_older_generation_allocation(size); bool first_only = ! should_try_older_generation_allocation(size);
@ -757,9 +743,7 @@ HeapWord* GenCollectorPolicy::satisfy_failed_allocation(size_t size,
is_tlab, // is_tlab is_tlab, // is_tlab
GenCollectedHeap::OldGen); // max_generation GenCollectedHeap::OldGen); // max_generation
} else { } else {
if (Verbose && PrintGCDetails) { log_trace(gc)(" :: Trying full because partial may fail :: ");
gclog_or_tty->print(" :: Trying full because partial may fail :: ");
}
// Try a full collection; see delta for bug id 6266275 // Try a full collection; see delta for bug id 6266275
// for the original code and why this has been simplified // for the original code and why this has been simplified
// with from-space allocation criteria modified and // with from-space allocation criteria modified and

View file

@ -125,36 +125,4 @@ class GCCause : public AllStatic {
static const char* to_string(GCCause::Cause cause); static const char* to_string(GCCause::Cause cause);
}; };
// Helper class for doing logging that includes the GC Cause
// as a string.
class GCCauseString : StackObj {
private:
static const int _length = 128;
char _buffer[_length];
int _position;
public:
GCCauseString(const char* prefix, GCCause::Cause cause) {
if (PrintGCCause) {
_position = jio_snprintf(_buffer, _length, "%s (%s) ", prefix, GCCause::to_string(cause));
} else {
_position = jio_snprintf(_buffer, _length, "%s ", prefix);
}
assert(_position >= 0 && _position <= _length,
"Need to increase the buffer size in GCCauseString? %d", _position);
}
GCCauseString& append(const char* str) {
int res = jio_snprintf(_buffer + _position, _length - _position, "%s", str);
_position += res;
assert(res >= 0 && _position <= _length,
"Need to increase the buffer size in GCCauseString? %d", res);
return *this;
}
operator const char*() {
return _buffer;
}
};
#endif // SHARE_VM_GC_SHARED_GCCAUSE_HPP #endif // SHARE_VM_GC_SHARED_GCCAUSE_HPP

View file

@ -26,6 +26,7 @@
#include "gc/shared/gcId.hpp" #include "gc/shared/gcId.hpp"
#include "runtime/safepoint.hpp" #include "runtime/safepoint.hpp"
#include "runtime/thread.inline.hpp" #include "runtime/thread.inline.hpp"
#include "runtime/threadLocalStorage.hpp"
uint GCId::_next_id = 0; uint GCId::_next_id = 0;
@ -47,6 +48,18 @@ const uint GCId::current_raw() {
return currentNamedthread()->gc_id(); return currentNamedthread()->gc_id();
} }
size_t GCId::print_prefix(char* buf, size_t len) {
if (ThreadLocalStorage::is_initialized() && ThreadLocalStorage::thread()->is_Named_thread()) {
uint gc_id = current_raw();
if (gc_id != undefined()) {
int ret = jio_snprintf(buf, len, "GC(%u) ", gc_id);
assert(ret > 0, "Failed to print prefix. Log buffer too small?");
return (size_t)ret;
}
}
return 0;
}
GCIdMark::GCIdMark() : _gc_id(GCId::create()) { GCIdMark::GCIdMark() : _gc_id(GCId::create()) {
currentNamedthread()->set_gc_id(_gc_id); currentNamedthread()->set_gc_id(_gc_id);
} }

View file

@ -40,6 +40,7 @@ class GCId : public AllStatic {
// Same as current() but can return undefined() if no GC id is currently active // Same as current() but can return undefined() if no GC id is currently active
static const uint current_raw(); static const uint current_raw();
static const uint undefined() { return UNDEFINED; } static const uint undefined() { return UNDEFINED; }
static size_t print_prefix(char* buf, size_t len);
}; };
class GCIdMark : public StackObj { class GCIdMark : public StackObj {

Some files were not shown because too many files have changed in this diff Show more