CRR (M): 7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
Tony Printezis
tony.printezis at oracle.com
Mon Aug 29 15:33:13 UTC 2011
Hi all,
I would like a couple of code reviews for this change which consolidates
and extends a lot of the ad-hoc ergonomic decision output we have in G1:
http://cr.openjdk.java.net/~tonyp/7050392/webrev.0/
This is the first batch of changes related to the ergonomic decision
output and covers decisions that affect the following heuristics:
* Heap Resizing : when and why we resize the heap
* CSet Construction : how we construct the collection set, which old
regions we add to it, when and why we stop adding old regions, etc.
* Concurrent Cycles : when we initiate a concurrent cycle and why,
what's the state of the heap at the end of a concurrent cycle, etc.
* Partially-Young GCs : when we start and end partially-young GCs and why
This will be extended with output for two additional heuristics
* Young Gen Sizing : how we grow the young gen, why we stop allocating
young gen regions, etc.
* Pause Prediction : details of how the pause prediction mechanism works
on a separate CR (7084525) as it requires some non-trivial code
refactoring (7084509). I decided to split the work into three CRs to
make the code reviews a bit more manageable.
Probably, the most controversial part of this CR are the set of macros I
introduced in order to generate the ergo decision records. I definitely
wanted to have a standard way to construct the records in order to
ensure consistency in their formatting (to make any potential parsing of
the output easier). But the problem is that different ergo decision
records have quite different information on them which made generating
them in a standard way quite tricky. So, this is the approach that I
took. Let's consider the following log record, which is in the format
generated by the new code:
8.675: [G1Ergonomics (Concurrent Cycles) request concurrent cycle
initiation, reason: occupancy higher than threshold, occupancy: 31346656
bytes, threshold: 30198960 bytes (45.00 %)]
The log record consists of the following:
1) 8.675 : a time stamp in the same format enabled with the
-XX:+PrintGCTimeStamps which is always enabled
2) [G1Ergonomics ... ] : standard prefix / suffix to be able to easily
identify such records
3) (Concurrent Cycles) : the heuristic the record corresponds to
4) request concurrent cycle initiation : a string describing the action
the ergonomic decision took
5) reason: occupancy higher than threshold : an optional string
describing the reason for the above action
6) occupancy / threshold : optional values that contributed to the decision
1), 2), 3), and 4) always appear on each record, 5) and 6) are optional.
I wanted each record to be printed with a single print command so that
it's not split by concurrent output. I also wanted the format string of
each record to be statically allocated to avoid having to stack-allocate
char[] buffers, etc. These two requirements, and the fact that some of
the compilers we use do not support var-arg macros, made constructing
the macros I needed a bit ugly. Here's an example of such a macro; in
fact it's the one that generates the above record (BTW: this is a good
time to take your anti-nausea medication):
ergo_verbose3(ErgoConcCycles,
"request concurrent cycle initiation",
ergo_reason_format("occupancy higher than threshold")
ergo_byte_format("occupancy")
ergo_byte_perc_format("threshold"),
cur_used_bytes,
min_used_targ, (double)
InitiatingHeapOccupancyPercent);
The parameters are:
arg 1 : The heuristic ID.
arg 2 : The action string.
arg 3 : Concatenation of the format string, generated using the
ergo_*_format() macros, that includes the optional parts of the record
(reason and values).
arg 4-6 : The optional values. Given that we don't have var-arg macros,
this takes exactly 3 extra args (which is why it's named
ergo_verbose3()). I have separate macros for between 0 and 6 args, they
are wrappers around a common macro, and they pass to it dummy values for
any args that are not needed.
I'm not 100% happy with this but I can't think of a better way to do
this. Let's go with it if it's not totally awful (or if there are no
better alternative suggestions).
Even though there's a fair amount of changes to the code, once you get
past the ergo_verbose*() macros and friends :-), the rest of the changes
are reasonably straightforward and mostly self-contained. I did very
light refactoring in a few places in order to split some code paths
which were taken by different ergonomic decisions so that I can generate
the appropriate output.
Tony
More information about the hotspot-gc-dev
mailing list