JDK-8212988 : add recent class unloading events to the hs_err log
Type:Enhancement
Component:hotspot
Sub-Component:runtime
Affected Version:12
Priority:P4
Status:Resolved
Resolution:Fixed
Submitted:2018-10-25
Updated:2019-08-15
Resolved:2019-02-13
The Version table provides details related to the release that this issue/RFE will be addressed.
Unresolved : Release in which this issue/RFE will be addressed. Resolved: Release in which this issue/RFE has been resolved. Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.
It could be helpful for debugging to include recent class unloading events in the hs_err
Comments
Good suggestion! We might be able to use this mechanism for logging exceptions too.
Classes unloaded (10 events):
Event: 3.629 Thread 0x00007fb41c25d800 Unloading class 0x0000000800256840 'javasoft/sqe/tests/lang/expr112/expr11201/expr11201'
Event: 3.629 Thread 0x00007fb41c25d800 Unloading class 0x0000000800256040 'javasoft/sqe/tests/lang/expr113/expr11301/expr11301'
Event: 3.629 Thread 0x00007fb41c25d800 Unloading class 0x0000000800255040 'javasoft/sqe/tests/lang/expr103/expr10303/expr10303'
Event: 3.629 Thread 0x00007fb41c25d800 Unloading class 0x0000000800254a50 'javasoft/sqe/tests/lang/expr104/expr10401/Calc'
Event: 3.629 Thread 0x00007fb41c25d800 Unloading class 0x0000000800254840 'javasoft/sqe/tests/lang/expr104/expr10401/expr10401'
Event: 3.629 Thread 0x00007fb41c25d800 Unloading class 0x0000000800254040 javasoft/sqe/tests/lang/expr106/expr10601/expr10601'
Event: 3.629 Thread 0x00007fb41c25d800 Unloading class 0x0000000800255840 'javasoft/sqe/tests/lang/expr107/expr10701/Triple'
Running until I get stable numbers that I like, this seems like it works.
$ bash get_avgs 143415 143756
Opening reference.numbers
average is 6.460699999999999
Opening less.logging.numbers
average is 6.218880000000001
11-02-2019
Maybe the number of messages might be the real problem. Most of the other events are somewhat coarse grained and are associated singly with expensive events, so the performance of the underlying log wasn't a major factor. Class unloading might produce a lot of events at once even though we only end up recording the last 10. I'd be curious if you greatly simplify the message but still keep the message per class if you still measure a performance difference. Maybe the locking overhead is significant? You could make a custom EventLog subclass that directly writes into the buffer instead of creating an intermediate resource string for the class name. I do think including the individual classes provides some extra clues that can be useful but the whole thing is surprisingly expensive.
11-02-2019
Yes, InstanceKlass::external_name() is very expensive because it changes '/' to '.' which we don't care about. If I changed to ik->name()->as_C_string() it's better but it's still slightly slower for the whole "Class Unloading" phase.
+ java avg less.logging.numbers
Opening less.logging.numbers
average is 6.952999999999999
+ java avg reference.unloading
Opening reference.unloading
average is 6.9037
Reporting just the class loader, with the address of the ClassLoaderData, might be just as helpful and doesn't cause any performance difference at all.
Classes unloaded (10 events):
Event: 0.635 Thread 0x00007ff52425d800 unloading class loader runThese$DirectoryClassLoader @124f97bc 0x00007ff47c033100
Event: 0.635 Thread 0x00007ff52425d800 unloading class loader runThese$DirectoryClassLoader @536d734f 0x00007ff49002d4b0
Event: 0.635 Thread 0x00007ff52425d800 unloading class loader runThese$DirectoryClassLoader @75ff9e63 0x00007ff47403b8c0
...
11-02-2019
Seems like a lot of cost for producing log messages. Maybe something is really inefficient about the string message production? The other downside of the EventLog is that it causes some serialization but I assume class unloading is serial anyway.
I'd added this locally when tracking JVMCI GC problems and wasn't sure of the source. The class unloading messages made it clearer where the bug was. It provides a nice clue that some unloading has occurred. Maybe it doesn't require the per class unloading messages? Maybe the class loader level detail is sufficient if the per class is too expensive.
08-02-2019
I was thinking these are such tiny numbers they probably don't matter but averaging total class unloading time for dacapo from these lines:
iteration.1/DaCapo2009/data/gc.log:[23.792s][debug][gc,phases] GC(12) Class Unloading 1.249ms
$ !java
java avg reference.unloading
Opening reference.unloading
average is 6.9037
$ java avg logging.unloading
Opening logging.unloading
average is 7.070959999999998
One extra ms average? Still a tiny number idk. [~stefank] ?
08-02-2019
I was doing some performance testing on this change with daCapo and the average ClassLoaderDataGraph times are higher with this logging. I took out logging the class loader name to see if that would help.
From 5 iterations of daCapo:
iteration.1/DaCapo2009/data/gc.log:[0.347s][debug][gc,phases] GC(0) ClassLoaderData 0.002ms
...
And running a small average script on the times:
$ java avg reference
Opening reference
average is 0.39697999999999994
$ java avg logging.new
Opening logging.new
average is 0.50326
The Events logging is on by default. I'm not really happy about this.
We thought this would be useful for another bug that we're looking at.
08-02-2019
We have a version of this in our JDK 8 sources that looks pretty much like yours though I left out the loader because I didn't really think of it. I'm happy if you are interested in taking it. I'd intended to bring it forward but I'll probably adopt your version in jvmci 8 just for consistency.
Class unloading (10 events):
Event: 6.930 Thread 0x00007fb64f078800 unloaded java.lang.invoke.LambdaForm$MH/1272457345 0x00000007c027e830
Event: 6.930 Thread 0x00007fb64f078800 unloaded com.oracle.svm.hosted.ImageClassLoader$1$$Lambda$57/805189653 0x00000007c027e430
Event: 6.930 Thread 0x00007fb64f078800 unloaded com.oracle.svm.hosted.ImageClassLoader$1$$Lambda$51/1970881185 0x00000007c027d830
Event: 6.930 Thread 0x00007fb64f078800 unloaded com.oracle.svm.hosted.ImageClassLoader$1$$Lambda$56/1681832320 0x00000007c027e030
Event: 6.930 Thread 0x00007fb64f078800 unloaded com.oracle.svm.hosted.ImageClassLoader$1$$Lambda$55/1774372677 0x00000007c027d030
Event: 6.930 Thread 0x00007fb64f078800 unloaded com.oracle.svm.hosted.ImageClassLoader$1$$Lambda$54/1338562892 0x00000007c027cc30
Event: 6.930 Thread 0x00007fb64f078800 unloaded com.oracle.svm.hosted.ImageClassLoader$1$$Lambda$53/1683266754 0x00000007c027dc30
Event: 6.930 Thread 0x00007fb64f078800 unloaded com.oracle.svm.hosted.ImageClassLoader$1$$Lambda$52/1159716434 0x00000007c027c830
Event: 18.511 Thread 0x00007fb64f078800 unloaded sun.reflect.GeneratedConstructorAccessor44 0x00000007c04bf030
Event: 18.511 Thread 0x00007fb64f078800 unloaded sun.reflect.GeneratedConstructorAccessor33 0x00000007c03d4430
08-02-2019
Classes unloaded (10 events):
Event: 1.342 Thread 0x00007f7084392800 unloading class javasoft.sqe.tests.lang.clss019.clss01901.clss01901 0x0000000800101040 in loader runThese$DirectoryClassLoader @5e14e5f1
Event: 1.342 Thread 0x00007f7084392800 unloading class javasoft.sqe.tests.lang.clss020.clss02001.clss02001_b 0x0000000800109840 in loader runThese$DirectoryClassLoader @28247928
Event: 1.342 Thread 0x00007f7084392800 unloading class javasoft.sqe.tests.lang.clss020.clss02001.clss02001_a 0x0000000800100c68 in loader runThese$DirectoryClassLoader @28247928
Event: 1.342 Thread 0x00007f7084392800 unloading class javasoft.sqe.tests.lang.clss020.clss02001.clss02001_i 0x0000000800100a58 in loader runThese$DirectoryClassLoader @28247928
Event: 1.342 Thread 0x00007f7084392800 unloading class javasoft.sqe.tests.lang.clss020.clss02001.clss02001 0x0000000800100840 in loader runThese$DirectoryClassLoader @28247928
Event: 1.342 Thread 0x00007f7084392800 unloading class javasoft.sqe.tests.lang.clss015.clss01501.clss01501 0x00000008000ff040 in loader runThese$DirectoryClassLoader @6f07bc49
Event: 1.342 Thread 0x00007f7084392800 unloading class javasoft.sqe.tests.lang.clss012.clss01215.aaa.bbb.ccc.clss01215_a 0x00000008000fea58 in loader runThese$DirectoryClassLoader @52442859
Event: 1.342 Thread 0x00007f7084392800 unloading class javasoft.sqe.tests.lang.clss012.clss01215.aaa.bbb.ccc.clss01215 0x00000008000fe840 in loader runThese$DirectoryClassLoader @52442859
Event: 1.342 Thread 0x00007f7084392800 unloading class javasoft.sqe.tests.lang.clss012.clss01214.aaa.bbb.ccc.clss01214_a 0x00000008000fda58 in loader runThese$DirectoryClassLoader @60a48bff
Event: 1.342 Thread 0x00007f7084392800 unloading class javasoft.sqe.tests.lang.clss012.clss01214.aaa.bbb.ccc.clss01214 0x00000008000fd840 in loader runThese$DirectoryClassLoader @60a48bff
07-02-2019
[~never] I'm going to take this (unless you already have the patch). Thanks.