<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
</head>
<body text="#000000" bgcolor="#FFFFFF">
Hi Bengt,<br>
<br>
Thanks for catching this.<br>
I think, that giving -XX:G1LogLevel="" should cause the VM start
error, because empty string is none of legal values.<br>
<br>
If you want to treat -XX:G1LogLevel="" as if unset, I can fix as you
said. <br>
I think it's not very important, because you are going to rewrite
this code soon.<br>
<br>
Thanks,<br>
Dima<br>
<br>
<br>
<br>
<br>
<div class="moz-cite-prefix">On 27.04.2015 18:55, Bengt Rutisson
wrote:<br>
</div>
<blockquote cite="mid:553E5BE5.4000400@oracle.com" type="cite">
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
<br>
Hi Dima,<br>
<br>
<div class="moz-cite-prefix">On 2015-04-27 15:32, Dmitry Fazunenko
wrote:<br>
</div>
<blockquote cite="mid:553E3A7A.4040008@oracle.com" type="cite">
<meta content="text/html; charset=UTF-8"
http-equiv="Content-Type">
Hi Bengt,<br>
<br>
Updated variant of fix with all your comments addressed:<br>
<br>
<a moz-do-not-send="true" class="moz-txt-link-freetext"
href="http://cr.openjdk.java.net/%7Edfazunen/8073476/webrev.08/">http://cr.openjdk.java.net/~dfazunen/8073476/webrev.08/</a><br>
</blockquote>
<br>
Thanks! Looks much better.<br>
<br>
One small detail. You have changed the behavior of this command
line:<br>
<br>
-XX:+UnlockExperimentalVMOptions -XX:G1LogLevel=""
-XX:+PrintGCDetails<br>
<br>
Before your change this would result in the log level being
"finer" due to the PrintGCDetails flag. But after your change we
will get log level None.<br>
<br>
It is not an interesting use case in my mind, but an easy fix
would be to introduce a state variable in G1Log to track whether
we should look at PrintGC* flags.<br>
<br>
So, in G1Log::init() you could do something like:<br>
<br>
_log_level_flag_used = G1LogLevel != NULL &&
G1LogLevel[0] != '\0';<br>
if (_log_level_flag_used) {<br>
<br>
} else <br>
update_level();<br>
}<br>
<br>
<br>
And update_level() would also look at the stat flag instead of
checking FLAG_IS_DEFAULT(G1LogLevel). That way init() and
update_level() would be consistent and we would keep the same
behavior as before your change.<br>
<br>
What do you think?<br>
<br>
Thanks,<br>
Bengt<br>
<br>
<br>
<br>
<blockquote cite="mid:553E3A7A.4040008@oracle.com" type="cite"> <br>
Thanks,<br>
Dima<br>
<br>
<br>
<div class="moz-cite-prefix">On 21.04.2015 16:18, Dmitry
Fazunenko wrote:<br>
</div>
<blockquote cite="mid:55364E19.8010207@oracle.com" type="cite">
<meta content="text/html; charset=UTF-8"
http-equiv="Content-Type">
Bengt,<br>
<br>
Thanks for your time!<br>
A have a question inline:<br>
<br>
<div class="moz-cite-prefix">On 21.04.2015 15:19, Bengt
Rutisson wrote:<br>
</div>
</blockquote>
<blockquote cite="mid:55364E19.8010207@oracle.com" type="cite">
<div class="moz-cite-prefix"> </div>
<blockquote cite="mid:5536405F.10104@oracle.com" type="cite">
<meta content="text/html; charset=UTF-8"
http-equiv="Content-Type">
<br>
Hi Dima,<br>
<br>
<div class="moz-cite-prefix">On 2015-04-21 13:33, Dmitry
Fazunenko wrote:<br>
</div>
<blockquote cite="mid:55363597.3040006@oracle.com"
type="cite">
<meta content="text/html; charset=UTF-8"
http-equiv="Content-Type">
<tt>Hi Bengt,<br>
<br>
This is modified fixed based on your comments:<br>
<a moz-do-not-send="true" class="moz-txt-link-freetext"
href="http://cr.openjdk.java.net/%7Edfazunen/8073476/webrev.07/">http://cr.openjdk.java.net/~dfazunen/8073476/webrev.07/</a><br>
<br>
Thanks for your assistance and good ideas!<br>
</tt></blockquote>
<br>
Thanks for making these change. Looks much better to me.<br>
<br>
A couple of comments:<br>
<br>
G1CollectedHeap::do_collection() is only used for full GCs.
You probably want to add a call to G1Log::update_level() in
G1CollectedHeap::do_collection_pause_at_safepoint() too to
make sure that it is called for young GCs as well.<br>
</blockquote>
<br>
agree. good catch!<br>
<br>
<blockquote cite="mid:5536405F.10104@oracle.com" type="cite">
<br>
<br>
I think it looks odd that G1Log::init() and
G1Log::update_level() use different guards for when to take
PrintGC and PrintGCDetails into account.<br>
<br>
51 void G1Log::init() {<br>
52 if (G1LogLevel != NULL && G1LogLevel[0] !=
'\0')<br>
<br>
37 void G1Log::update_level() {<br>
38 if (FLAG_IS_DEFAULT(G1LogLevel)) {<br>
<br>
Is there a difference between (G1LogLevel != NULL &&
G1LogLevel[0] != '\0') and (FLAG_IS_DEFAULT(G1LogLevel)) ?
Can we use the same guard in both places?<br>
</blockquote>
<br>
I though about using the same expression in both cases. The
difference in handling the empty value: -XX:G1LogLevel= <br>
So, the question, how this case should be handled:<br>
- a warning to be printed out and level set to 'none'<br>
- treated in the same way as 'none'<br>
<br>
<br>
<blockquote cite="mid:5536405F.10104@oracle.com" type="cite">
<br>
<br>
g1Log.hpp:<br>
<br>
I don't think this comment helps much:<br>
<br>
+ // to be invoked on VM start <br>
static void init();<br>
<br>
The name init() makes it pretty clear to me what the method
is expected to do. I would just leave the comment out.<br>
</blockquote>
I have a bit different vision, but I'm okay to remove the
comment<br>
<br>
<br>
<blockquote cite="mid:5536405F.10104@oracle.com" type="cite">
<br>
The comment for update_level() talks about where the method
should be called instead of what it does. That is normally
not such a good thing for comments. Better to explain what
it does so it can be called in all places where it is needed
in the future.<br>
<br>
So instead of:<br>
<br>
+ // to be invoked on GC start or flag values change<br>
+ static void update_level();<br>
<br>
I would prefer:<br>
<br>
// Update the log level to reflect runtime changes to
manageable flags.<br>
</blockquote>
agree.<br>
<br>
Thanks,<br>
Dima<br>
<br>
<br>
<blockquote cite="mid:5536405F.10104@oracle.com" type="cite">
<br>
Thanks,<br>
Bengt<br>
<br>
<blockquote cite="mid:55363597.3040006@oracle.com"
type="cite"><tt> <br>
-- Dima<br>
<br>
<br>
</tt>
<div class="moz-cite-prefix">On 20.04.2015 11:34, Bengt
Rutisson wrote:<br>
</div>
<blockquote cite="mid:5534BA0B.5010906@oracle.com"
type="cite">
<meta content="text/html; charset=UTF-8"
http-equiv="Content-Type">
<br>
Hi Dima,<br>
<br>
<div class="moz-cite-prefix">On 2015-04-17 15:51, Dmitry
Fazunenko wrote:<br>
</div>
<blockquote cite="mid:55310FCF.5030109@oracle.com"
type="cite">
<meta content="text/html; charset=UTF-8"
http-equiv="Content-Type">
<tt>Bengt,<br>
<br>
Please find comments inline.<br>
<br>
</tt>
<div class="moz-cite-prefix">On 17.04.2015 9:43, Bengt
Rutisson wrote:<br>
</div>
<blockquote cite="mid:5530AB92.2050509@oracle.com"
type="cite">
<meta content="text/html; charset=UTF-8"
http-equiv="Content-Type">
<br>
Hi Dima,<br>
<br>
<div class="moz-cite-prefix">On 2015-04-16 15:36,
Dmitry Fazunenko wrote:<br>
</div>
<blockquote cite="mid:552FBAF5.1060908@oracle.com"
type="cite">
<meta content="text/html; charset=UTF-8"
http-equiv="Content-Type">
Hi Bengt,<br>
<br>
thanks for looking.<br>
<br>
<div class="moz-cite-prefix">On 16.04.2015 15:42,
Bengt Rutisson wrote:<br>
</div>
<blockquote cite="mid:552FAE22.4020009@oracle.com"
type="cite">
<meta content="text/html; charset=UTF-8"
http-equiv="Content-Type">
<br>
Hello Dima,<br>
<br>
<div class="moz-cite-prefix">On 2015-04-16
13:40, Dmitry Fazunenko wrote:<br>
</div>
<blockquote
cite="mid:552F9FA8.3030403@oracle.com"
type="cite">
<meta http-equiv="content-type"
content="text/html; charset=UTF-8">
Hello,<br>
<br>
Would you review a simple fix in G1.<br>
<br>
Short description: <br>
after introduction G1Log - dynamic changes of
PrintGC and PrintGCDetails flag has no effect
anymore, because G1Log looks for these flags
during initialization only. The fix: sync the
log level with the flags values.<br>
<br>
A huge thanks to Jesper who helped me a lot
with my first product fix.<br>
<br>
Bug: <a moz-do-not-send="true"
class="moz-txt-link-freetext"
href="https://bugs.openjdk.java.net/browse/JDK-8073476">https://bugs.openjdk.java.net/browse/JDK-8073476</a><br>
Webrev: <a moz-do-not-send="true"
class="moz-txt-link-freetext"
href="http://cr.openjdk.java.net/%7Edfazunen/8073476/webrev.06/">http://cr.openjdk.java.net/~dfazunen/8073476/webrev.06/</a><br>
</blockquote>
<br>
Sorry, but I don't really like the way this is
solved. With this approach calling
G1GCPhaseTimes::print() suddenly has the side
effect that it resets the log level. That's
quite unexpected for me. Especially if you
consider the code path in
G1CollectedHeap::log_gc_footer() where we do
this:<br>
<br>
void G1CollectedHeap::log_gc_footer(double
pause_time_sec) {<br>
if (!G1Log::fine()) {<br>
return;<br>
}<br>
<br>
if (G1Log::finer()) {<br>
...<br>
g1_policy()->phase_times()->print(pause_time_sec);<br>
...<br>
}<br>
<br>
If we don't have G1Log::fine() (which is
PrintGC) enabled we will never call the print()
method and will thus not detect any changes made
by the MXBean. If we have G1Log::finer() enabled
we enter the logging code, print other things at
the "finer" level (which is PrintGCDetails) and
then do the call to the print() method where we
can suddenly decide that PrintGCDetails no
longer is enabled and not do the rest of the
logging. So for the same GC we will print some
stuff at PrintGCDetails level and some things at
another level. Strange.<br>
</blockquote>
<br>
May it's not clear, but the change will have
effect only if PrintGC or PrintGCDetails has been
changed during execution.<br>
Otherwise, the level will not change.<br>
</blockquote>
<br>
I understand that, but what I was saying with the
example above is that you will not get the desired
effect if you change PrintGC or PrintGCDetails at
runtime. If they are disabled, and then turn them on
at runtime you will not enter the update code
because of this check at the start of the
log_gc_footer() method:<br>
<br>
if (!G1Log::fine()) {<br>
return;<br>
}<br>
<br>
<br>
Similarly turning them off at runtime will start to
have an effect in the middle of a GC. Which is
probably not the effect you are looking for.<br>
</blockquote>
fine() invokes level(), level() invokes update(), so
G1::fine() will return the up to date value:<br>
<br>
<pre> inline static bool fine() {
<span class="removed">- return _level >= LevelFine;</span>
<span class="new">+ return level() >= LevelFine;</span>
}</pre>
<br>
<pre> static LogLevel level() {
<span class="new">+ // PringGC and PrintGCDetails are dynamic flags</span>
<span class="new">+ // _level should be in sync with the latest values</span>
<span class="new">+ update_level();</span>
return _level;
}</pre>
<br>
</blockquote>
Oh, I missed that you had changed fine() to call
level(). This means that all calls to G1Log interface
has side effects. I don't like that at all.<br>
<br>
<blockquote cite="mid:55310FCF.5030109@oracle.com"
type="cite">
<blockquote cite="mid:5530AB92.2050509@oracle.com"
type="cite"> <br>
This is why making the level() getter having the
side effect of changing the log level is a bad idea.
You have no control over when that happens.<br>
</blockquote>
<br>
It must be up to those who change flags at runtime.<br>
But the following code should work:<br>
<br>
MXBean.set(PrintGC, false);<br>
System.gc();<br>
MXBean.set(PrintGC, true);<br>
<br>
<blockquote cite="mid:5530AB92.2050509@oracle.com"
type="cite"> <br>
<blockquote cite="mid:552FBAF5.1060908@oracle.com"
type="cite"> <br>
To me, it's strange, that when I disable PrintGC
in G1 I still seeing gc log messages... <br>
Or, I can't turn logging on during execution with
G1.<br>
This works well for other collectors.<br>
<br>
Would it make sense to make PrintGC and
PrintGCDetails unmanageable in case of g1?<br>
</blockquote>
<br>
I think they can be manageble but their changed
states need to be handled more explicitly.<br>
<br>
<blockquote cite="mid:552FBAF5.1060908@oracle.com"
type="cite"> <br>
<br>
<blockquote cite="mid:552FAE22.4020009@oracle.com"
type="cite"> <br>
<br>
I would prefer to have a hook when the MXBean
changes the value and only update the level at
that point.<br>
</blockquote>
<br>
Yes, it would be ideal solution. But I haven't
found such a mechanism supported. And it's
unlikely worth adding just for this case.<br>
In my version, the sync will be done more
frequently. <br>
</blockquote>
<br>
The sync is done very frequently. Actually way too
often in my view.<br>
</blockquote>
<blockquote cite="mid:5530AB92.2050509@oracle.com"
type="cite"> <br>
I would prefer that you investigate the hook in the
MXBean change so we know how much work that would
be. </blockquote>
<br>
It was my first intention, but I haven't found a way
how to implement it.<br>
</blockquote>
<br>
I think what you need to do is to extend the Flag class
with an update() method and call the method in
WriteableFlags::set_flag().<br>
<br>
<blockquote cite="mid:55310FCF.5030109@oracle.com"
type="cite"> <br>
<blockquote cite="mid:5530AB92.2050509@oracle.com"
type="cite">If that is not possible I think a better
solution is to call G1Log::update_level() *once* at
the start of a GC. That way the log level is always
consistent throughout the GC.<br>
</blockquote>
<br>
Yes, this is a good idea!<br>
</blockquote>
<br>
Yes, it is much cleaner.<br>
<br>
<blockquote cite="mid:55310FCF.5030109@oracle.com"
type="cite"> <br>
<blockquote cite="mid:5530AB92.2050509@oracle.com"
type="cite"> <br>
<blockquote cite="mid:552FBAF5.1060908@oracle.com"
type="cite"> <br>
<blockquote cite="mid:552FAE22.4020009@oracle.com"
type="cite"> <br>
Having said that I am not sure that this bug is
worth fixing right now. I am currently working
on the JEP to make the GC logging use the new
unified logging format. That will change all of
this and most likely remove the G1Log class all
together. So, my suggestion would be to leave
this as is for now and instead add the MXBean
requirement to the unified logging work.<br>
</blockquote>
<br>
Yes, I'm aware of unified logging and expect that
G1Log class will go away someday.<br>
But I would like to be able to disable logging in
JDK9, to not see GC events occurred at the certain
period of time.<br>
</blockquote>
<br>
Can you explain more why this is important to fix
right now? Unified logging is targeted for JDK 9.<br>
</blockquote>
<br>
What I heard about unified logging is that there is no
guarantee that it will happen in JDK9 time frame.<br>
I need the feature now to develop tests based on
analysis of logs: I want to start logging not from
begging, but after some steps.<br>
<br>
Will you be okay if G1Log::update_level() is invoked
once per GC?<br>
</blockquote>
<br>
I would be ok with it, but I'm pretty convinced unified
logging will make it in to JDK9 so if you can wait for
it that might be better.<br>
<br>
Thanks,<br>
Bengt<br>
<br>
<blockquote cite="mid:55310FCF.5030109@oracle.com"
type="cite"> <br>
Thanks,<br>
Dima<br>
<br>
<blockquote cite="mid:5530AB92.2050509@oracle.com"
type="cite"> <br>
Thanks,<br>
Bengt<br>
<br>
<blockquote cite="mid:552FBAF5.1060908@oracle.com"
type="cite"> <br>
Thanks,<br>
Dima<br>
<br>
<br>
<blockquote cite="mid:552FAE22.4020009@oracle.com"
type="cite"> <br>
Thanks,<br>
Bengt<br>
<blockquote
cite="mid:552F9FA8.3030403@oracle.com"
type="cite"> <br>
Testing: <br>
I ran manually the test from the bug report to
make sure the change fixes the problem.<br>
A regression test will be delivered separately
as a fix of <a moz-do-not-send="true"
id="key-val" rel="4774806"
href="https://bugs.openjdk.java.net/browse/JDK-8077056">JDK-8077056</a><br>
<br>
Thanks,<br>
Dima </blockquote>
<br>
</blockquote>
<br>
</blockquote>
<br>
</blockquote>
<br>
</blockquote>
<br>
</blockquote>
<br>
</blockquote>
<br>
</blockquote>
<br>
</blockquote>
<br>
</blockquote>
<br>
</blockquote>
<br>
</body>
</html>