提交 77dfa5f1 编写于 作者: J jcoomes

Merge

...@@ -6332,10 +6332,10 @@ void CMSCollector::reset(bool asynch) { ...@@ -6332,10 +6332,10 @@ void CMSCollector::reset(bool asynch) {
) )
} }
void CMSCollector::do_CMS_operation(CMS_op_type op) { void CMSCollector::do_CMS_operation(CMS_op_type op, GCCause::Cause gc_cause) {
gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps); gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
TraceTime t("GC", PrintGC, !PrintGCDetails, gclog_or_tty); TraceTime t(GCCauseString("GC", gc_cause), PrintGC, !PrintGCDetails, gclog_or_tty);
TraceCollectorStats tcs(counters()); TraceCollectorStats tcs(counters());
switch (op) { switch (op) {
......
...@@ -717,7 +717,7 @@ class CMSCollector: public CHeapObj { ...@@ -717,7 +717,7 @@ class CMSCollector: public CHeapObj {
CMS_op_checkpointRootsFinal CMS_op_checkpointRootsFinal
}; };
void do_CMS_operation(CMS_op_type op); void do_CMS_operation(CMS_op_type op, GCCause::Cause gc_cause);
bool stop_world_and_do(CMS_op_type op); bool stop_world_and_do(CMS_op_type op);
OopTaskQueueSet* task_queues() { return _task_queues; } OopTaskQueueSet* task_queues() { return _task_queues; }
......
...@@ -146,7 +146,7 @@ void VM_CMS_Initial_Mark::doit() { ...@@ -146,7 +146,7 @@ void VM_CMS_Initial_Mark::doit() {
VM_CMS_Operation::verify_before_gc(); VM_CMS_Operation::verify_before_gc();
IsGCActiveMark x; // stop-world GC active IsGCActiveMark x; // stop-world GC active
_collector->do_CMS_operation(CMSCollector::CMS_op_checkpointRootsInitial); _collector->do_CMS_operation(CMSCollector::CMS_op_checkpointRootsInitial, gch->gc_cause());
VM_CMS_Operation::verify_after_gc(); VM_CMS_Operation::verify_after_gc();
#ifndef USDT2 #ifndef USDT2
...@@ -178,7 +178,7 @@ void VM_CMS_Final_Remark::doit() { ...@@ -178,7 +178,7 @@ void VM_CMS_Final_Remark::doit() {
VM_CMS_Operation::verify_before_gc(); VM_CMS_Operation::verify_before_gc();
IsGCActiveMark x; // stop-world GC active IsGCActiveMark x; // stop-world GC active
_collector->do_CMS_operation(CMSCollector::CMS_op_checkpointRootsFinal); _collector->do_CMS_operation(CMSCollector::CMS_op_checkpointRootsFinal, gch->gc_cause());
VM_CMS_Operation::verify_after_gc(); VM_CMS_Operation::verify_after_gc();
#ifndef USDT2 #ifndef USDT2
......
...@@ -1252,10 +1252,7 @@ bool G1CollectedHeap::do_collection(bool explicit_gc, ...@@ -1252,10 +1252,7 @@ bool G1CollectedHeap::do_collection(bool explicit_gc,
gclog_or_tty->date_stamp(G1Log::fine() && PrintGCDateStamps); gclog_or_tty->date_stamp(G1Log::fine() && PrintGCDateStamps);
TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty); TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty);
char verbose_str[128]; TraceTime t(GCCauseString("Full GC", gc_cause()), G1Log::fine(), true, gclog_or_tty);
sprintf(verbose_str, "Full GC (%s)", GCCause::to_string(gc_cause()));
TraceTime t(verbose_str, G1Log::fine(), true, gclog_or_tty);
TraceCollectorStats tcs(g1mm()->full_collection_counters()); TraceCollectorStats tcs(g1mm()->full_collection_counters());
TraceMemoryManagerStats tms(true /* fullGC */, gc_cause()); TraceMemoryManagerStats tms(true /* fullGC */, gc_cause());
...@@ -3600,12 +3597,10 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) { ...@@ -3600,12 +3597,10 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) {
gclog_or_tty->date_stamp(G1Log::fine() && PrintGCDateStamps); gclog_or_tty->date_stamp(G1Log::fine() && PrintGCDateStamps);
TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty); TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty);
char verbose_str[128]; GCCauseString gc_cause_str = GCCauseString("GC pause", gc_cause())
sprintf(verbose_str, "GC pause (%s) (%s)%s", .append(g1_policy()->gcs_are_young() ? " (young)" : " (mixed)")
GCCause::to_string(gc_cause()), .append(g1_policy()->during_initial_mark_pause() ? " (initial-mark)" : "");
g1_policy()->gcs_are_young() ? "young" : "mixed", TraceTime t(gc_cause_str, G1Log::fine() && !G1Log::finer(), true, gclog_or_tty);
g1_policy()->during_initial_mark_pause() ? " (initial-mark)" : "");
TraceTime t(verbose_str, G1Log::fine() && !G1Log::finer(), true, gclog_or_tty);
TraceCollectorStats tcs(g1mm()->incremental_collection_counters()); TraceCollectorStats tcs(g1mm()->incremental_collection_counters());
TraceMemoryManagerStats tms(false /* fullGC */, gc_cause()); TraceMemoryManagerStats tms(false /* fullGC */, gc_cause());
...@@ -5502,7 +5497,7 @@ void G1CollectedHeap::evacuate_collection_set() { ...@@ -5502,7 +5497,7 @@ void G1CollectedHeap::evacuate_collection_set() {
if (evacuation_failed()) { if (evacuation_failed()) {
remove_self_forwarding_pointers(); remove_self_forwarding_pointers();
if (G1Log::finer()) { if (G1Log::finer()) {
gclog_or_tty->print(" (to-space overflow)"); gclog_or_tty->print(" (to-space exhausted)");
} else if (G1Log::fine()) { } else if (G1Log::fine()) {
gclog_or_tty->print("--"); gclog_or_tty->print("--");
} }
......
...@@ -886,9 +886,8 @@ void G1CollectorPolicy::record_collection_pause_start(double start_time_sec, ...@@ -886,9 +886,8 @@ void G1CollectorPolicy::record_collection_pause_start(double start_time_sec,
size_t start_used) { size_t start_used) {
if (G1Log::finer()) { if (G1Log::finer()) {
gclog_or_tty->stamp(PrintGCTimeStamps); gclog_or_tty->stamp(PrintGCTimeStamps);
gclog_or_tty->print("[GC pause (%s) (%s)", gclog_or_tty->print("[%s", (const char*)GCCauseString("GC pause", _g1->gc_cause())
GCCause::to_string(_g1->gc_cause()), .append(gcs_are_young() ? " (young)" : " (mixed)"));
gcs_are_young() ? "young" : "mixed");
} }
// We only need to do this here as the policy will only be applied // We only need to do this here as the policy will only be applied
...@@ -1010,7 +1009,8 @@ T sum_of(T* sum_arr, int start, int n, int N) { ...@@ -1010,7 +1009,8 @@ T sum_of(T* sum_arr, int start, int n, int N) {
void G1CollectorPolicy::print_par_stats(int level, void G1CollectorPolicy::print_par_stats(int level,
const char* str, const char* str,
double* data) { double* data,
bool showDecimals) {
double min = data[0], max = data[0]; double min = data[0], max = data[0];
double total = 0.0; double total = 0.0;
LineBuffer buf(level); LineBuffer buf(level);
...@@ -1023,7 +1023,11 @@ void G1CollectorPolicy::print_par_stats(int level, ...@@ -1023,7 +1023,11 @@ void G1CollectorPolicy::print_par_stats(int level,
max = val; max = val;
total += val; total += val;
if (G1Log::finest()) { if (G1Log::finest()) {
buf.append(" %.1lf", val); if (showDecimals) {
buf.append(" %.1lf", val);
} else {
buf.append(" %d", (int)val);
}
} }
} }
...@@ -1031,36 +1035,26 @@ void G1CollectorPolicy::print_par_stats(int level, ...@@ -1031,36 +1035,26 @@ void G1CollectorPolicy::print_par_stats(int level,
buf.append_and_print_cr(""); buf.append_and_print_cr("");
} }
double avg = total / (double) no_of_gc_threads(); double avg = total / (double) no_of_gc_threads();
buf.append_and_print_cr(" Avg: %.1lf Min: %.1lf Max: %.1lf Diff: %.1lf]", if (showDecimals) {
avg, min, max, max - min); buf.append_and_print_cr(" Min: %.1lf, Avg: %.1lf, Max: %.1lf, Diff: %.1lf, Sum: %.1lf]",
} min, avg, max, max - min, total);
} else {
void G1CollectorPolicy::print_par_sizes(int level, buf.append_and_print_cr(" Min: %d, Avg: %d, Max: %d, Diff: %d, Sum: %d]",
const char* str, (int)min, (int)avg, (int)max, (int)max - (int)min, (int)total);
double* data) {
double min = data[0], max = data[0];
double total = 0.0;
LineBuffer buf(level);
buf.append("[%s :", str);
for (uint i = 0; i < no_of_gc_threads(); ++i) {
double val = data[i];
if (val < min)
min = val;
if (val > max)
max = val;
total += val;
buf.append(" %d", (int) val);
} }
buf.append_and_print_cr("");
double avg = total / (double) no_of_gc_threads();
buf.append_and_print_cr(" Sum: %d, Avg: %d, Min: %d, Max: %d, Diff: %d]",
(int)total, (int)avg, (int)min, (int)max, (int)max - (int)min);
} }
void G1CollectorPolicy::print_stats(int level, void G1CollectorPolicy::print_stats(int level,
const char* str, const char* str,
double value) { double value) {
LineBuffer(level).append_and_print_cr("[%s: %5.1lf ms]", str, value); LineBuffer(level).append_and_print_cr("[%s: %.1lf ms]", str, value);
}
void G1CollectorPolicy::print_stats(int level,
const char* str,
double value,
int workers) {
LineBuffer(level).append_and_print_cr("[%s: %.1lf ms, GC Workers: %d]", str, value, workers);
} }
void G1CollectorPolicy::print_stats(int level, void G1CollectorPolicy::print_stats(int level,
...@@ -1373,7 +1367,7 @@ void G1CollectorPolicy::record_collection_pause_end(int no_of_gc_threads) { ...@@ -1373,7 +1367,7 @@ void G1CollectorPolicy::record_collection_pause_end(int no_of_gc_threads) {
print_stats(1, "Root Region Scan Waiting", _root_region_scan_wait_time_ms); print_stats(1, "Root Region Scan Waiting", _root_region_scan_wait_time_ms);
} }
if (parallel) { if (parallel) {
print_stats(1, "Parallel Time", _cur_collection_par_time_ms); print_stats(1, "Parallel Time", _cur_collection_par_time_ms, no_of_gc_threads);
print_par_stats(2, "GC Worker Start", _par_last_gc_worker_start_times_ms); print_par_stats(2, "GC Worker Start", _par_last_gc_worker_start_times_ms);
print_par_stats(2, "Ext Root Scanning", _par_last_ext_root_scan_times_ms); print_par_stats(2, "Ext Root Scanning", _par_last_ext_root_scan_times_ms);
if (print_marking_info) { if (print_marking_info) {
...@@ -1381,13 +1375,15 @@ void G1CollectorPolicy::record_collection_pause_end(int no_of_gc_threads) { ...@@ -1381,13 +1375,15 @@ void G1CollectorPolicy::record_collection_pause_end(int no_of_gc_threads) {
} }
print_par_stats(2, "Update RS", _par_last_update_rs_times_ms); print_par_stats(2, "Update RS", _par_last_update_rs_times_ms);
if (G1Log::finest()) { if (G1Log::finest()) {
print_par_sizes(3, "Processed Buffers", _par_last_update_rs_processed_buffers); print_par_stats(3, "Processed Buffers", _par_last_update_rs_processed_buffers,
false /* showDecimals */);
} }
print_par_stats(2, "Scan RS", _par_last_scan_rs_times_ms); print_par_stats(2, "Scan RS", _par_last_scan_rs_times_ms);
print_par_stats(2, "Object Copy", _par_last_obj_copy_times_ms); print_par_stats(2, "Object Copy", _par_last_obj_copy_times_ms);
print_par_stats(2, "Termination", _par_last_termination_times_ms); print_par_stats(2, "Termination", _par_last_termination_times_ms);
if (G1Log::finest()) { if (G1Log::finest()) {
print_par_sizes(3, "Termination Attempts", _par_last_termination_attempts); print_par_stats(3, "Termination Attempts", _par_last_termination_attempts,
false /* showDecimals */);
} }
for (int i = 0; i < _parallel_gc_threads; i++) { for (int i = 0; i < _parallel_gc_threads; i++) {
...@@ -1601,9 +1597,9 @@ void G1CollectorPolicy::record_collection_pause_end(int no_of_gc_threads) { ...@@ -1601,9 +1597,9 @@ void G1CollectorPolicy::record_collection_pause_end(int no_of_gc_threads) {
_collectionSetChooser->verify(); _collectionSetChooser->verify();
} }
#define EXT_SIZE_FORMAT "%d%s" #define EXT_SIZE_FORMAT "%.1f%s"
#define EXT_SIZE_PARAMS(bytes) \ #define EXT_SIZE_PARAMS(bytes) \
byte_size_in_proper_unit((bytes)), \ byte_size_in_proper_unit((double)(bytes)), \
proper_unit_for_byte_size((bytes)) proper_unit_for_byte_size((bytes))
void G1CollectorPolicy::print_heap_transition() { void G1CollectorPolicy::print_heap_transition() {
......
...@@ -552,10 +552,10 @@ public: ...@@ -552,10 +552,10 @@ public:
private: private:
void print_stats(int level, const char* str, double value); void print_stats(int level, const char* str, double value);
void print_stats(int level, const char* str, double value, int workers);
void print_stats(int level, const char* str, int value); void print_stats(int level, const char* str, int value);
void print_par_stats(int level, const char* str, double* data); void print_par_stats(int level, const char* str, double* data, bool showDecimals = true);
void print_par_sizes(int level, const char* str, double* data);
void check_other_times(int level, void check_other_times(int level,
NumberSeq* other_times_ms, NumberSeq* other_times_ms,
......
...@@ -42,6 +42,7 @@ VM_G1CollectForAllocation::VM_G1CollectForAllocation( ...@@ -42,6 +42,7 @@ VM_G1CollectForAllocation::VM_G1CollectForAllocation(
void VM_G1CollectForAllocation::doit() { void VM_G1CollectForAllocation::doit() {
G1CollectedHeap* g1h = G1CollectedHeap::heap(); G1CollectedHeap* g1h = G1CollectedHeap::heap();
GCCauseSetter x(g1h, _gc_cause);
_result = g1h->satisfy_failed_allocation(_word_size, &_pause_succeeded); _result = g1h->satisfy_failed_allocation(_word_size, &_pause_succeeded);
assert(_result == NULL || _pause_succeeded, assert(_result == NULL || _pause_succeeded,
"if we get back a result, the pause should have succeeded"); "if we get back a result, the pause should have succeeded");
......
...@@ -916,7 +916,7 @@ void ParNewGeneration::collect(bool full, ...@@ -916,7 +916,7 @@ void ParNewGeneration::collect(bool full,
size_policy->minor_collection_begin(); size_policy->minor_collection_begin();
} }
TraceTime t1("GC", PrintGC && !PrintGCDetails, true, gclog_or_tty); TraceTime t1(GCCauseString("GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, gclog_or_tty);
// Capture heap used before collection (for printing). // Capture heap used before collection (for printing).
size_t gch_prev_used = gch->used(); size_t gch_prev_used = gch->used();
......
...@@ -160,16 +160,10 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) { ...@@ -160,16 +160,10 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
{ {
HandleMark hm; HandleMark hm;
const bool is_system_gc = gc_cause == GCCause::_java_lang_system_gc;
// This is useful for debugging but don't change the output the
// the customer sees.
const char* gc_cause_str = "Full GC";
if (is_system_gc && PrintGCDetails) {
gc_cause_str = "Full GC (System)";
}
gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps); gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
TraceTime t1(gc_cause_str, PrintGC, !PrintGCDetails, gclog_or_tty); TraceTime t1(GCCauseString("Full GC", gc_cause), PrintGC, !PrintGCDetails, gclog_or_tty);
TraceCollectorStats tcs(counters()); TraceCollectorStats tcs(counters());
TraceMemoryManagerStats tms(true /* Full GC */,gc_cause); TraceMemoryManagerStats tms(true /* Full GC */,gc_cause);
......
...@@ -2047,17 +2047,9 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) { ...@@ -2047,17 +2047,9 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) {
gc_task_manager()->task_idle_workers(); gc_task_manager()->task_idle_workers();
heap->set_par_threads(gc_task_manager()->active_workers()); heap->set_par_threads(gc_task_manager()->active_workers());
const bool is_system_gc = gc_cause == GCCause::_java_lang_system_gc;
// This is useful for debugging but don't change the output the
// the customer sees.
const char* gc_cause_str = "Full GC";
if (is_system_gc && PrintGCDetails) {
gc_cause_str = "Full GC (System)";
}
gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps); gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
TraceTime t1(gc_cause_str, PrintGC, !PrintGCDetails, gclog_or_tty); TraceTime t1(GCCauseString("Full GC", gc_cause), PrintGC, !PrintGCDetails, gclog_or_tty);
TraceCollectorStats tcs(counters()); TraceCollectorStats tcs(counters());
TraceMemoryManagerStats tms(true /* Full GC */,gc_cause); TraceMemoryManagerStats tms(true /* Full GC */,gc_cause);
...@@ -2090,7 +2082,8 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) { ...@@ -2090,7 +2082,8 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) {
} }
#endif // #ifndef PRODUCT #endif // #ifndef PRODUCT
bool max_on_system_gc = UseMaximumCompactionOnSystemGC && is_system_gc; bool max_on_system_gc = UseMaximumCompactionOnSystemGC
&& gc_cause == GCCause::_java_lang_system_gc;
summary_phase(vmthread_cm, maximum_heap_compaction || max_on_system_gc); summary_phase(vmthread_cm, maximum_heap_compaction || max_on_system_gc);
COMPILER2_PRESENT(assert(DerivedPointerTable::is_active(), "Sanity")); COMPILER2_PRESENT(assert(DerivedPointerTable::is_active(), "Sanity"));
......
...@@ -325,7 +325,7 @@ bool PSScavenge::invoke_no_policy() { ...@@ -325,7 +325,7 @@ bool PSScavenge::invoke_no_policy() {
gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps); gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
TraceTime t1("GC", PrintGC, !PrintGCDetails, gclog_or_tty); TraceTime t1(GCCauseString("GC", gc_cause), PrintGC, !PrintGCDetails, gclog_or_tty);
TraceCollectorStats tcs(counters()); TraceCollectorStats tcs(counters());
TraceMemoryManagerStats tms(false /* not full GC */,gc_cause); TraceMemoryManagerStats tms(false /* not full GC */,gc_cause);
......
...@@ -31,9 +31,15 @@ float AdaptiveWeightedAverage::compute_adaptive_average(float new_sample, ...@@ -31,9 +31,15 @@ float AdaptiveWeightedAverage::compute_adaptive_average(float new_sample,
float average) { float average) {
// We smooth the samples by not using weight() directly until we've // We smooth the samples by not using weight() directly until we've
// had enough data to make it meaningful. We'd like the first weight // had enough data to make it meaningful. We'd like the first weight
// used to be 1, the second to be 1/2, etc until we have 100/weight // used to be 1, the second to be 1/2, etc until we have
// samples. // OLD_THRESHOLD/weight samples.
unsigned count_weight = 100/count(); unsigned count_weight = 0;
// Avoid division by zero if the counter wraps (7158457)
if (!is_old()) {
count_weight = OLD_THRESHOLD/count();
}
unsigned adaptive_weight = (MAX2(weight(), count_weight)); unsigned adaptive_weight = (MAX2(weight(), count_weight));
float new_avg = exp_avg(average, new_sample, adaptive_weight); float new_avg = exp_avg(average, new_sample, adaptive_weight);
...@@ -43,8 +49,6 @@ float AdaptiveWeightedAverage::compute_adaptive_average(float new_sample, ...@@ -43,8 +49,6 @@ float AdaptiveWeightedAverage::compute_adaptive_average(float new_sample,
void AdaptiveWeightedAverage::sample(float new_sample) { void AdaptiveWeightedAverage::sample(float new_sample) {
increment_count(); increment_count();
assert(count() != 0,
"Wraparound -- history would be incorrectly discarded");
// Compute the new weighted average // Compute the new weighted average
float new_avg = compute_adaptive_average(new_sample, average()); float new_avg = compute_adaptive_average(new_sample, average());
......
...@@ -50,11 +50,20 @@ class AdaptiveWeightedAverage : public CHeapObj { ...@@ -50,11 +50,20 @@ class AdaptiveWeightedAverage : public CHeapObj {
unsigned _weight; // The weight used to smooth the averages unsigned _weight; // The weight used to smooth the averages
// A higher weight favors the most // A higher weight favors the most
// recent data. // recent data.
bool _is_old; // Has enough historical data
const static unsigned OLD_THRESHOLD = 100;
protected: protected:
float _last_sample; // The last value sampled. float _last_sample; // The last value sampled.
void increment_count() { _sample_count++; } void increment_count() {
_sample_count++;
if (!_is_old && _sample_count > OLD_THRESHOLD) {
_is_old = true;
}
}
void set_average(float avg) { _average = avg; } void set_average(float avg) { _average = avg; }
// Helper function, computes an adaptive weighted average // Helper function, computes an adaptive weighted average
...@@ -64,13 +73,15 @@ class AdaptiveWeightedAverage : public CHeapObj { ...@@ -64,13 +73,15 @@ class AdaptiveWeightedAverage : public CHeapObj {
public: public:
// Input weight must be between 0 and 100 // Input weight must be between 0 and 100
AdaptiveWeightedAverage(unsigned weight, float avg = 0.0) : AdaptiveWeightedAverage(unsigned weight, float avg = 0.0) :
_average(avg), _sample_count(0), _weight(weight), _last_sample(0.0) { _average(avg), _sample_count(0), _weight(weight), _last_sample(0.0),
_is_old(false) {
} }
void clear() { void clear() {
_average = 0; _average = 0;
_sample_count = 0; _sample_count = 0;
_last_sample = 0; _last_sample = 0;
_is_old = false;
} }
// Useful for modifying static structures after startup. // Useful for modifying static structures after startup.
...@@ -84,7 +95,8 @@ class AdaptiveWeightedAverage : public CHeapObj { ...@@ -84,7 +95,8 @@ class AdaptiveWeightedAverage : public CHeapObj {
float average() const { return _average; } float average() const { return _average; }
unsigned weight() const { return _weight; } unsigned weight() const { return _weight; }
unsigned count() const { return _sample_count; } unsigned count() const { return _sample_count; }
float last_sample() const { return _last_sample; } float last_sample() const { return _last_sample; }
bool is_old() const { return _is_old; }
// Update data with a new sample. // Update data with a new sample.
void sample(float new_sample); void sample(float new_sample);
......
...@@ -88,4 +88,36 @@ class GCCause : public AllStatic { ...@@ -88,4 +88,36 @@ 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,
err_msg("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,
err_msg("Need to increase the buffer size in GCCauseString? %d", res));
return *this;
}
operator const char*() {
return _buffer;
}
};
#endif // SHARE_VM_GC_INTERFACE_GCCAUSE_HPP #endif // SHARE_VM_GC_INTERFACE_GCCAUSE_HPP
...@@ -548,7 +548,7 @@ void DefNewGeneration::collect(bool full, ...@@ -548,7 +548,7 @@ void DefNewGeneration::collect(bool full,
init_assuming_no_promotion_failure(); init_assuming_no_promotion_failure();
TraceTime t1("GC", PrintGC && !PrintGCDetails, true, gclog_or_tty); TraceTime t1(GCCauseString("GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, gclog_or_tty);
// Capture heap used before collection (for printing). // Capture heap used before collection (for printing).
size_t gch_prev_used = gch->used(); size_t gch_prev_used = gch->used();
......
...@@ -480,26 +480,15 @@ void GenCollectedHeap::do_collection(bool full, ...@@ -480,26 +480,15 @@ void GenCollectedHeap::do_collection(bool full,
const size_t perm_prev_used = perm_gen()->used(); const size_t perm_prev_used = perm_gen()->used();
print_heap_before_gc(); print_heap_before_gc();
if (Verbose) {
gclog_or_tty->print_cr("GC Cause: %s", GCCause::to_string(gc_cause()));
}
{ {
FlagSetting fl(_is_gc_active, true); FlagSetting fl(_is_gc_active, true);
bool complete = full && (max_level == (n_gens()-1)); bool complete = full && (max_level == (n_gens()-1));
const char* gc_cause_str = "GC "; const char* gc_cause_prefix = complete ? "Full GC" : "GC";
if (complete) {
GCCause::Cause cause = gc_cause();
if (cause == GCCause::_java_lang_system_gc) {
gc_cause_str = "Full GC (System) ";
} else {
gc_cause_str = "Full GC ";
}
}
gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps); gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
TraceTime t(gc_cause_str, PrintGCDetails, false, gclog_or_tty); TraceTime t(GCCauseString(gc_cause_prefix, gc_cause()), PrintGCDetails, false, gclog_or_tty);
gc_prologue(complete); gc_prologue(complete);
increment_total_collections(complete); increment_total_collections(complete);
......
...@@ -76,7 +76,7 @@ void GenMarkSweep::invoke_at_safepoint(int level, ReferenceProcessor* rp, ...@@ -76,7 +76,7 @@ void GenMarkSweep::invoke_at_safepoint(int level, ReferenceProcessor* rp,
_ref_processor = rp; _ref_processor = rp;
rp->setup_policy(clear_all_softrefs); rp->setup_policy(clear_all_softrefs);
TraceTime t1("Full GC", PrintGC && !PrintGCDetails, true, gclog_or_tty); TraceTime t1(GCCauseString("Full GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, gclog_or_tty);
// When collecting the permanent generation methodOops may be moving, // When collecting the permanent generation methodOops may be moving,
// so we either have to flush all bcp data or convert it into bci. // so we either have to flush all bcp data or convert it into bci.
......
...@@ -3092,6 +3092,14 @@ jint Arguments::parse(const JavaVMInitArgs* args) { ...@@ -3092,6 +3092,14 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
PrintGC = true; PrintGC = true;
} }
if (!JDK_Version::is_gte_jdk18x_version()) {
// To avoid changing the log format for 7 updates this flag is only
// true by default in JDK8 and above.
if (FLAG_IS_DEFAULT(PrintGCCause)) {
FLAG_SET_DEFAULT(PrintGCCause, false);
}
}
// Set object alignment values. // Set object alignment values.
set_object_alignment(); set_object_alignment();
......
...@@ -3902,7 +3902,10 @@ class CommandLineFlags { ...@@ -3902,7 +3902,10 @@ class CommandLineFlags {
" of this flag is true for JDK 6 and earlier") \ " of this flag is true for JDK 6 and earlier") \
\ \
diagnostic(bool, WhiteBoxAPI, false, \ diagnostic(bool, WhiteBoxAPI, false, \
"Enable internal testing APIs") "Enable internal testing APIs") \
\
product(bool, PrintGCCause, true, \
"Include GC cause in GC logging")
/* /*
* Macros for factoring of globals * Macros for factoring of globals
......
...@@ -206,6 +206,10 @@ class JDK_Version VALUE_OBJ_CLASS_SPEC { ...@@ -206,6 +206,10 @@ class JDK_Version VALUE_OBJ_CLASS_SPEC {
return current().compare_major(7) == 0; return current().compare_major(7) == 0;
} }
static bool is_jdk18x_version() {
return current().compare_major(8) == 0;
}
static bool is_gte_jdk13x_version() { static bool is_gte_jdk13x_version() {
return current().compare_major(3) >= 0; return current().compare_major(3) >= 0;
} }
...@@ -225,6 +229,10 @@ class JDK_Version VALUE_OBJ_CLASS_SPEC { ...@@ -225,6 +229,10 @@ class JDK_Version VALUE_OBJ_CLASS_SPEC {
static bool is_gte_jdk17x_version() { static bool is_gte_jdk17x_version() {
return current().compare_major(7) >= 0; return current().compare_major(7) >= 0;
} }
static bool is_gte_jdk18x_version() {
return current().compare_major(8) >= 0;
}
}; };
#endif // SHARE_VM_RUNTIME_JAVA_HPP #endif // SHARE_VM_RUNTIME_JAVA_HPP
/* /*
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -179,6 +179,11 @@ const jlong NANOSECS_PER_SEC = CONST64(1000000000); ...@@ -179,6 +179,11 @@ const jlong NANOSECS_PER_SEC = CONST64(1000000000);
const jint NANOSECS_PER_MILLISEC = 1000000; const jint NANOSECS_PER_MILLISEC = 1000000;
inline const char* proper_unit_for_byte_size(size_t s) { inline const char* proper_unit_for_byte_size(size_t s) {
#ifdef _LP64
if (s >= 10*G) {
return "G";
}
#endif
if (s >= 10*M) { if (s >= 10*M) {
return "M"; return "M";
} else if (s >= 10*K) { } else if (s >= 10*K) {
...@@ -188,17 +193,22 @@ inline const char* proper_unit_for_byte_size(size_t s) { ...@@ -188,17 +193,22 @@ inline const char* proper_unit_for_byte_size(size_t s) {
} }
} }
inline size_t byte_size_in_proper_unit(size_t s) { template <class T>
inline T byte_size_in_proper_unit(T s) {
#ifdef _LP64
if (s >= 10*G) {
return (T)(s/G);
}
#endif
if (s >= 10*M) { if (s >= 10*M) {
return s/M; return (T)(s/M);
} else if (s >= 10*K) { } else if (s >= 10*K) {
return s/K; return (T)(s/K);
} else { } else {
return s; return s;
} }
} }
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
// VM type definitions // VM type definitions
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册