mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-21 11:34:38 +02:00
6871111: G1: remove the concurrent overhead tracker
Removing the concurrent overhead tracker from G1, along with the GC overhead reporter and the G1AccountConcurrentOverhead (both of which rely on the the concurrent overhead tracker). Reviewed-by: iveresov, johnc
This commit is contained in:
parent
ead860c069
commit
4d138cd094
19 changed files with 9 additions and 887 deletions
|
@ -1,189 +0,0 @@
|
|||
/*
|
||||
* Copyright 2001-2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*
|
||||
*/
|
||||
|
||||
# include "incls/_precompiled.incl"
|
||||
# include "incls/_coTracker.cpp.incl"
|
||||
|
||||
COTracker* COTracker::_head = NULL;
|
||||
double COTracker::_cpu_number = -1.0;
|
||||
|
||||
void
|
||||
COTracker::resetPeriod(double now_sec, double vnow_sec) {
|
||||
guarantee( _enabled, "invariant" );
|
||||
_period_start_time_sec = now_sec;
|
||||
_period_start_vtime_sec = vnow_sec;
|
||||
}
|
||||
|
||||
void
|
||||
COTracker::setConcOverhead(double time_stamp_sec,
|
||||
double conc_overhead) {
|
||||
guarantee( _enabled, "invariant" );
|
||||
_conc_overhead = conc_overhead;
|
||||
_time_stamp_sec = time_stamp_sec;
|
||||
if (conc_overhead > 0.001)
|
||||
_conc_overhead_seq.add(conc_overhead);
|
||||
}
|
||||
|
||||
void
|
||||
COTracker::reset(double starting_conc_overhead) {
|
||||
guarantee( _enabled, "invariant" );
|
||||
double now_sec = os::elapsedTime();
|
||||
setConcOverhead(now_sec, starting_conc_overhead);
|
||||
}
|
||||
|
||||
void
|
||||
COTracker::start() {
|
||||
guarantee( _enabled, "invariant" );
|
||||
resetPeriod(os::elapsedTime(), os::elapsedVTime());
|
||||
}
|
||||
|
||||
void
|
||||
COTracker::update(bool force_end) {
|
||||
assert( _enabled, "invariant" );
|
||||
double end_time_sec = os::elapsedTime();
|
||||
double elapsed_time_sec = end_time_sec - _period_start_time_sec;
|
||||
if (force_end || elapsed_time_sec > _update_period_sec) {
|
||||
// reached the end of the period
|
||||
double end_vtime_sec = os::elapsedVTime();
|
||||
double elapsed_vtime_sec = end_vtime_sec - _period_start_vtime_sec;
|
||||
|
||||
double conc_overhead = elapsed_vtime_sec / elapsed_time_sec;
|
||||
|
||||
setConcOverhead(end_time_sec, conc_overhead);
|
||||
resetPeriod(end_time_sec, end_vtime_sec);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
COTracker::updateForSTW(double start_sec, double end_sec) {
|
||||
if (!_enabled)
|
||||
return;
|
||||
|
||||
// During a STW pause, no concurrent GC thread has done any
|
||||
// work. So, we can safely adjust the start of the current period by
|
||||
// adding the duration of the STW pause to it, so that the STW pause
|
||||
// doesn't affect the reading of the concurrent overhead (it's
|
||||
// basically like excluding the time of the STW pause from the
|
||||
// concurrent overhead calculation).
|
||||
|
||||
double stw_duration_sec = end_sec - start_sec;
|
||||
guarantee( stw_duration_sec > 0.0, "invariant" );
|
||||
|
||||
if (outOfDate(start_sec))
|
||||
_conc_overhead = 0.0;
|
||||
else
|
||||
_time_stamp_sec = end_sec;
|
||||
_period_start_time_sec += stw_duration_sec;
|
||||
_conc_overhead_seq = NumberSeq();
|
||||
|
||||
guarantee( os::elapsedTime() > _period_start_time_sec, "invariant" );
|
||||
}
|
||||
|
||||
double
|
||||
COTracker::predConcOverhead() {
|
||||
if (_enabled) {
|
||||
// tty->print(" %1.2lf", _conc_overhead_seq.maximum());
|
||||
return _conc_overhead_seq.maximum();
|
||||
} else {
|
||||
// tty->print(" DD");
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
COTracker::resetPred() {
|
||||
_conc_overhead_seq = NumberSeq();
|
||||
}
|
||||
|
||||
COTracker::COTracker(int group)
|
||||
: _enabled(false),
|
||||
_group(group),
|
||||
_period_start_time_sec(-1.0),
|
||||
_period_start_vtime_sec(-1.0),
|
||||
_conc_overhead(-1.0),
|
||||
_time_stamp_sec(-1.0),
|
||||
_next(NULL) {
|
||||
// GCOverheadReportingPeriodMS indicates how frequently the
|
||||
// concurrent overhead will be recorded by the GC Overhead
|
||||
// Reporter. We want to take readings less often than that. If we
|
||||
// took readings more often than some of them might be lost.
|
||||
_update_period_sec = ((double) GCOverheadReportingPeriodMS) / 1000.0 * 1.25;
|
||||
_next = _head;
|
||||
_head = this;
|
||||
|
||||
if (_cpu_number < 0.0)
|
||||
_cpu_number = (double) os::processor_count();
|
||||
}
|
||||
|
||||
// statics
|
||||
|
||||
void
|
||||
COTracker::updateAllForSTW(double start_sec, double end_sec) {
|
||||
for (COTracker* curr = _head; curr != NULL; curr = curr->_next) {
|
||||
curr->updateForSTW(start_sec, end_sec);
|
||||
}
|
||||
}
|
||||
|
||||
double
|
||||
COTracker::totalConcOverhead(double now_sec) {
|
||||
double total_conc_overhead = 0.0;
|
||||
|
||||
for (COTracker* curr = _head; curr != NULL; curr = curr->_next) {
|
||||
double conc_overhead = curr->concOverhead(now_sec);
|
||||
total_conc_overhead += conc_overhead;
|
||||
}
|
||||
|
||||
return total_conc_overhead;
|
||||
}
|
||||
|
||||
double
|
||||
COTracker::totalConcOverhead(double now_sec,
|
||||
size_t group_num,
|
||||
double* co_per_group) {
|
||||
double total_conc_overhead = 0.0;
|
||||
|
||||
for (size_t i = 0; i < group_num; ++i)
|
||||
co_per_group[i] = 0.0;
|
||||
|
||||
for (COTracker* curr = _head; curr != NULL; curr = curr->_next) {
|
||||
size_t group = curr->_group;
|
||||
assert( 0 <= group && group < group_num, "invariant" );
|
||||
double conc_overhead = curr->concOverhead(now_sec);
|
||||
|
||||
co_per_group[group] += conc_overhead;
|
||||
total_conc_overhead += conc_overhead;
|
||||
}
|
||||
|
||||
return total_conc_overhead;
|
||||
}
|
||||
|
||||
double
|
||||
COTracker::totalPredConcOverhead() {
|
||||
double total_pred_conc_overhead = 0.0;
|
||||
for (COTracker* curr = _head; curr != NULL; curr = curr->_next) {
|
||||
total_pred_conc_overhead += curr->predConcOverhead();
|
||||
curr->resetPred();
|
||||
}
|
||||
return total_pred_conc_overhead / _cpu_number;
|
||||
}
|
|
@ -1,181 +0,0 @@
|
|||
/*
|
||||
* Copyright 2001-2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*
|
||||
*/
|
||||
|
||||
// COTracker keeps track of the concurrent overhead of a GC thread.
|
||||
|
||||
// A thread that needs to be tracked must, itself, start up its
|
||||
// tracker with the start() method and then call the update() method
|
||||
// at regular intervals. What the tracker does is to calculate the
|
||||
// concurrent overhead of a process at a given update period. The
|
||||
// tracker starts and when is detects that it has exceeded the given
|
||||
// period, it calculates the duration of the period in wall-clock time
|
||||
// and the duration of the period in vtime (i.e. how much time the
|
||||
// concurrent processes really took up during this period). The ratio
|
||||
// of the latter over the former is the concurrent overhead of that
|
||||
// process for that period over a single CPU. This overhead is stored
|
||||
// on the tracker, "timestamped" with the wall-clock time of the end
|
||||
// of the period. When the concurrent overhead of this process needs
|
||||
// to be queried, this last "reading" provides a good approximation
|
||||
// (we assume that the concurrent overhead of a particular thread
|
||||
// stays largely constant over time). The timestamp is necessary to
|
||||
// detect when the process has stopped working and the recorded
|
||||
// reading hasn't been updated for some time.
|
||||
|
||||
// Each concurrent GC thread is considered to be part of a "group"
|
||||
// (i.e. any available concurrent marking threads are part of the
|
||||
// "concurrent marking thread group"). A COTracker is associated with
|
||||
// a single group at construction-time. It's up to each collector to
|
||||
// decide how groups will be mapped to such an id (ids should start
|
||||
// from 0 and be consecutive; there's a hardcoded max group num
|
||||
// defined on the GCOverheadTracker class). The notion of a group has
|
||||
// been introduced to be able to identify how much overhead was
|
||||
// imposed by each group, instead of getting a single value that
|
||||
// covers all concurrent overhead.
|
||||
|
||||
class COTracker {
|
||||
private:
|
||||
// It indicates whether this tracker is enabled or not. When the
|
||||
// tracker is disabled, then it returns 0.0 as the latest concurrent
|
||||
// overhead and several methods (reset, start, and update) are not
|
||||
// supposed to be called on it. This enabling / disabling facility
|
||||
// is really provided to make a bit more explicit in the code when a
|
||||
// particulary tracker of a processes that doesn't run all the time
|
||||
// (e.g. concurrent marking) is supposed to be used and not it's not.
|
||||
bool _enabled;
|
||||
|
||||
// The ID of the group associated with this tracker.
|
||||
int _group;
|
||||
|
||||
// The update period of the tracker. A new value for the concurrent
|
||||
// overhead of the associated process will be made at intervals no
|
||||
// smaller than this.
|
||||
double _update_period_sec;
|
||||
|
||||
// The start times (both wall-block time and vtime) of the current
|
||||
// interval.
|
||||
double _period_start_time_sec;
|
||||
double _period_start_vtime_sec;
|
||||
|
||||
// Number seq of the concurrent overhead readings within a period
|
||||
NumberSeq _conc_overhead_seq;
|
||||
|
||||
// The latest reading of the concurrent overhead (over a single CPU)
|
||||
// imposed by the associated concurrent thread, made available at
|
||||
// the indicated wall-clock time.
|
||||
double _conc_overhead;
|
||||
double _time_stamp_sec;
|
||||
|
||||
// The number of CPUs that the host machine has (for convenience
|
||||
// really, as we'd have to keep translating it into a double)
|
||||
static double _cpu_number;
|
||||
|
||||
// Fields that keep a list of all trackers created. This is useful,
|
||||
// since it allows us to sum up the concurrent overhead without
|
||||
// having to write code for a specific collector to broadcast a
|
||||
// request to all its concurrent processes.
|
||||
COTracker* _next;
|
||||
static COTracker* _head;
|
||||
|
||||
// It indicates that a new period is starting by updating the
|
||||
// _period_start_time_sec and _period_start_vtime_sec fields.
|
||||
void resetPeriod(double now_sec, double vnow_sec);
|
||||
// It updates the latest concurrent overhead reading, taken at a
|
||||
// given wall-clock time.
|
||||
void setConcOverhead(double time_stamp_sec, double conc_overhead);
|
||||
|
||||
// It determines whether the time stamp of the latest concurrent
|
||||
// overhead reading is out of date or not.
|
||||
bool outOfDate(double now_sec) {
|
||||
// The latest reading is considered out of date, if it was taken
|
||||
// 1.2x the update period.
|
||||
return (now_sec - _time_stamp_sec) > 1.2 * _update_period_sec;
|
||||
}
|
||||
|
||||
public:
|
||||
// The constructor which associates the tracker with a group ID.
|
||||
COTracker(int group);
|
||||
|
||||
// Methods to enable / disable the tracker and query whether it is enabled.
|
||||
void enable() { _enabled = true; }
|
||||
void disable() { _enabled = false; }
|
||||
bool enabled() { return _enabled; }
|
||||
|
||||
// It resets the tracker and sets concurrent overhead reading to be
|
||||
// the given parameter and the associated time stamp to be now.
|
||||
void reset(double starting_conc_overhead = 0.0);
|
||||
// The tracker starts tracking. IT should only be called from the
|
||||
// concurrent thread that is tracked by this tracker.
|
||||
void start();
|
||||
// It updates the tracker and, if the current period is longer than
|
||||
// the update period, the concurrent overhead reading will be
|
||||
// updated. force_end being true indicates that it's the last call
|
||||
// to update() by this process before the tracker is disabled (the
|
||||
// tracker can be re-enabled later if necessary). It should only be
|
||||
// called from the concurrent thread that is tracked by this tracker
|
||||
// and while the thread has joined the STS.
|
||||
void update(bool force_end = false);
|
||||
// It adjusts the contents of the tracker to take into account a STW
|
||||
// pause.
|
||||
void updateForSTW(double start_sec, double end_sec);
|
||||
|
||||
// It returns the last concurrent overhead reading over a single
|
||||
// CPU. If the reading is out of date, or the tracker is disabled,
|
||||
// it returns 0.0.
|
||||
double concCPUOverhead(double now_sec) {
|
||||
if (!_enabled || outOfDate(now_sec))
|
||||
return 0.0;
|
||||
else
|
||||
return _conc_overhead;
|
||||
}
|
||||
|
||||
// It returns the last concurrent overhead reading over all CPUs
|
||||
// that the host machine has. If the reading is out of date, or the
|
||||
// tracker is disabled, it returns 0.0.
|
||||
double concOverhead(double now_sec) {
|
||||
return concCPUOverhead(now_sec) / _cpu_number;
|
||||
}
|
||||
|
||||
double predConcOverhead();
|
||||
|
||||
void resetPred();
|
||||
|
||||
// statics
|
||||
|
||||
// It notifies all trackers about a STW pause.
|
||||
static void updateAllForSTW(double start_sec, double end_sec);
|
||||
|
||||
// It returns the sum of the concurrent overhead readings of all
|
||||
// available (and enabled) trackers for the given time stamp. The
|
||||
// overhead is over all the CPUs of the host machine.
|
||||
|
||||
static double totalConcOverhead(double now_sec);
|
||||
// Like the previous method, but it also sums up the overheads per
|
||||
// group number. The length of the co_per_group array must be at
|
||||
// least as large group_num
|
||||
static double totalConcOverhead(double now_sec,
|
||||
size_t group_num,
|
||||
double* co_per_group);
|
||||
|
||||
static double totalPredConcOverhead();
|
||||
};
|
|
@ -1,179 +0,0 @@
|
|||
/*
|
||||
* Copyright 2001-2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*
|
||||
*/
|
||||
|
||||
# include "incls/_precompiled.incl"
|
||||
# include "incls/_gcOverheadReporter.cpp.incl"
|
||||
|
||||
class COReportingThread : public ConcurrentGCThread {
|
||||
private:
|
||||
GCOverheadReporter* _reporter;
|
||||
|
||||
public:
|
||||
COReportingThread(GCOverheadReporter* reporter) : _reporter(reporter) {
|
||||
guarantee( _reporter != NULL, "precondition" );
|
||||
create_and_start();
|
||||
}
|
||||
|
||||
virtual void run() {
|
||||
initialize_in_thread();
|
||||
wait_for_universe_init();
|
||||
|
||||
int period_ms = GCOverheadReportingPeriodMS;
|
||||
|
||||
while ( true ) {
|
||||
os::sleep(Thread::current(), period_ms, false);
|
||||
|
||||
_sts.join();
|
||||
double now_sec = os::elapsedTime();
|
||||
_reporter->collect_and_record_conc_overhead(now_sec);
|
||||
_sts.leave();
|
||||
}
|
||||
|
||||
terminate();
|
||||
}
|
||||
};
|
||||
|
||||
GCOverheadReporter* GCOverheadReporter::_reporter = NULL;
|
||||
|
||||
GCOverheadReporter::GCOverheadReporter(size_t group_num,
|
||||
const char* group_names[],
|
||||
size_t length)
|
||||
: _group_num(group_num), _prev_end_sec(0.0) {
|
||||
guarantee( 0 <= group_num && group_num <= MaxGCOverheadGroupNum,
|
||||
"precondition" );
|
||||
|
||||
_base = NEW_C_HEAP_ARRAY(GCOverheadReporterEntry, length);
|
||||
_top = _base + length;
|
||||
_curr = _base;
|
||||
|
||||
for (size_t i = 0; i < group_num; ++i) {
|
||||
guarantee( group_names[i] != NULL, "precondition" );
|
||||
_group_names[i] = group_names[i];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GCOverheadReporter::add(double start_sec, double end_sec,
|
||||
double* conc_overhead,
|
||||
double stw_overhead) {
|
||||
assert( _curr <= _top, "invariant" );
|
||||
|
||||
if (_curr == _top) {
|
||||
guarantee( false, "trace full" );
|
||||
return;
|
||||
}
|
||||
|
||||
_curr->_start_sec = start_sec;
|
||||
_curr->_end_sec = end_sec;
|
||||
for (size_t i = 0; i < _group_num; ++i) {
|
||||
_curr->_conc_overhead[i] =
|
||||
(conc_overhead != NULL) ? conc_overhead[i] : 0.0;
|
||||
}
|
||||
_curr->_stw_overhead = stw_overhead;
|
||||
|
||||
++_curr;
|
||||
}
|
||||
|
||||
void
|
||||
GCOverheadReporter::collect_and_record_conc_overhead(double end_sec) {
|
||||
double start_sec = _prev_end_sec;
|
||||
guarantee( end_sec > start_sec, "invariant" );
|
||||
|
||||
double conc_overhead[MaxGCOverheadGroupNum];
|
||||
COTracker::totalConcOverhead(end_sec, _group_num, conc_overhead);
|
||||
add_conc_overhead(start_sec, end_sec, conc_overhead);
|
||||
_prev_end_sec = end_sec;
|
||||
}
|
||||
|
||||
void
|
||||
GCOverheadReporter::record_stw_start(double start_sec) {
|
||||
guarantee( start_sec > _prev_end_sec, "invariant" );
|
||||
collect_and_record_conc_overhead(start_sec);
|
||||
}
|
||||
|
||||
void
|
||||
GCOverheadReporter::record_stw_end(double end_sec) {
|
||||
double start_sec = _prev_end_sec;
|
||||
COTracker::updateAllForSTW(start_sec, end_sec);
|
||||
add_stw_overhead(start_sec, end_sec, 1.0);
|
||||
|
||||
_prev_end_sec = end_sec;
|
||||
}
|
||||
|
||||
void
|
||||
GCOverheadReporter::print() const {
|
||||
tty->print_cr("");
|
||||
tty->print_cr("GC Overhead (%d entries)", _curr - _base);
|
||||
tty->print_cr("");
|
||||
GCOverheadReporterEntry* curr = _base;
|
||||
while (curr < _curr) {
|
||||
double total = curr->_stw_overhead;
|
||||
for (size_t i = 0; i < _group_num; ++i)
|
||||
total += curr->_conc_overhead[i];
|
||||
|
||||
tty->print("OVERHEAD %12.8lf %12.8lf ",
|
||||
curr->_start_sec, curr->_end_sec);
|
||||
|
||||
for (size_t i = 0; i < _group_num; ++i)
|
||||
tty->print("%s %12.8lf ", _group_names[i], curr->_conc_overhead[i]);
|
||||
|
||||
tty->print_cr("STW %12.8lf TOT %12.8lf", curr->_stw_overhead, total);
|
||||
++curr;
|
||||
}
|
||||
tty->print_cr("");
|
||||
}
|
||||
|
||||
// statics
|
||||
|
||||
void
|
||||
GCOverheadReporter::initGCOverheadReporter(size_t group_num,
|
||||
const char* group_names[]) {
|
||||
guarantee( _reporter == NULL, "should only be called once" );
|
||||
guarantee( 0 <= group_num && group_num <= MaxGCOverheadGroupNum,
|
||||
"precondition" );
|
||||
guarantee( group_names != NULL, "pre-condition" );
|
||||
|
||||
if (GCOverheadReporting) {
|
||||
_reporter = new GCOverheadReporter(group_num, group_names);
|
||||
new COReportingThread(_reporter);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GCOverheadReporter::recordSTWStart(double start_sec) {
|
||||
if (_reporter != NULL)
|
||||
_reporter->record_stw_start(start_sec);
|
||||
}
|
||||
|
||||
void
|
||||
GCOverheadReporter::recordSTWEnd(double end_sec) {
|
||||
if (_reporter != NULL)
|
||||
_reporter->record_stw_end(end_sec);
|
||||
}
|
||||
|
||||
void
|
||||
GCOverheadReporter::printGCOverhead() {
|
||||
if (_reporter != NULL)
|
||||
_reporter->print();
|
||||
}
|
|
@ -1,141 +0,0 @@
|
|||
/*
|
||||
* Copyright 2001-2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*
|
||||
*/
|
||||
|
||||
// Keeps track of the GC overhead (both concurrent and STW). It stores
|
||||
// it in a large array and then prints it to tty at the end of the
|
||||
// execution.
|
||||
|
||||
// See coTracker.hpp for the explanation on what groups are.
|
||||
|
||||
// Let's set a maximum number of concurrent overhead groups, to
|
||||
// statically allocate any arrays we need and not to have to
|
||||
// malloc/free them. This is just a bit more convenient.
|
||||
enum {
|
||||
MaxGCOverheadGroupNum = 4
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
double _start_sec;
|
||||
double _end_sec;
|
||||
|
||||
double _conc_overhead[MaxGCOverheadGroupNum];
|
||||
double _stw_overhead;
|
||||
} GCOverheadReporterEntry;
|
||||
|
||||
class GCOverheadReporter {
|
||||
friend class COReportingThread;
|
||||
|
||||
private:
|
||||
enum PrivateConstants {
|
||||
DefaultReporterLength = 128 * 1024
|
||||
};
|
||||
|
||||
// Reference to the single instance of this class.
|
||||
static GCOverheadReporter* _reporter;
|
||||
|
||||
// These three references point to the array that contains the GC
|
||||
// overhead entries (_base is the base of the array, _top is the
|
||||
// address passed the last entry of the array, _curr is the next
|
||||
// entry to be used).
|
||||
GCOverheadReporterEntry* _base;
|
||||
GCOverheadReporterEntry* _top;
|
||||
GCOverheadReporterEntry* _curr;
|
||||
|
||||
// The number of concurrent overhead groups.
|
||||
size_t _group_num;
|
||||
|
||||
// The wall-clock time of the end of the last recorded period of GC
|
||||
// overhead.
|
||||
double _prev_end_sec;
|
||||
|
||||
// Names for the concurrent overhead groups.
|
||||
const char* _group_names[MaxGCOverheadGroupNum];
|
||||
|
||||
// Add a new entry to the large array. conc_overhead being NULL is
|
||||
// equivalent to an array full of 0.0s. conc_overhead should have a
|
||||
// length of at least _group_num.
|
||||
void add(double start_sec, double end_sec,
|
||||
double* conc_overhead,
|
||||
double stw_overhead);
|
||||
|
||||
// Add an entry that represents concurrent GC overhead.
|
||||
// conc_overhead must be at least of length _group_num.
|
||||
// conc_overhead being NULL is equivalent to an array full of 0.0s.
|
||||
void add_conc_overhead(double start_sec, double end_sec,
|
||||
double* conc_overhead) {
|
||||
add(start_sec, end_sec, conc_overhead, 0.0);
|
||||
}
|
||||
|
||||
// Add an entry that represents STW GC overhead.
|
||||
void add_stw_overhead(double start_sec, double end_sec,
|
||||
double stw_overhead) {
|
||||
add(start_sec, end_sec, NULL, stw_overhead);
|
||||
}
|
||||
|
||||
// It records the start of a STW pause (i.e. it records the
|
||||
// concurrent overhead up to that point)
|
||||
void record_stw_start(double start_sec);
|
||||
|
||||
// It records the end of a STW pause (i.e. it records the overhead
|
||||
// associated with the pause and adjusts all the trackers to reflect
|
||||
// the pause)
|
||||
void record_stw_end(double end_sec);
|
||||
|
||||
// It queries all the trackers of their concurrent overhead and
|
||||
// records it.
|
||||
void collect_and_record_conc_overhead(double end_sec);
|
||||
|
||||
// It prints the contents of the GC overhead array
|
||||
void print() const;
|
||||
|
||||
|
||||
// Constructor. The same preconditions for group_num and group_names
|
||||
// from initGCOverheadReporter apply here too.
|
||||
GCOverheadReporter(size_t group_num,
|
||||
const char* group_names[],
|
||||
size_t length = DefaultReporterLength);
|
||||
|
||||
public:
|
||||
|
||||
// statics
|
||||
|
||||
// It initialises the GCOverheadReporter and launches the concurrent
|
||||
// overhead reporting thread. Both actions happen only if the
|
||||
// GCOverheadReporting parameter is set. The length of the
|
||||
// group_names array should be >= group_num and group_num should be
|
||||
// <= MaxGCOverheadGroupNum. Entries group_namnes[0..group_num-1]
|
||||
// should not be NULL.
|
||||
static void initGCOverheadReporter(size_t group_num,
|
||||
const char* group_names[]);
|
||||
|
||||
// The following three are provided for convenience and they are
|
||||
// wrappers around record_stw_start(start_sec), record_stw_end(end_sec),
|
||||
// and print(). Each of these checks whether GC overhead reporting
|
||||
// is on (i.e. _reporter != NULL) and, if it is, calls the
|
||||
// corresponding method. Saves from repeating this pattern again and
|
||||
// again from the places where they need to be called.
|
||||
static void recordSTWStart(double start_sec);
|
||||
static void recordSTWEnd(double end_sec);
|
||||
static void printGCOverhead();
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue