-
Notifications
You must be signed in to change notification settings - Fork 937
Heatmap converter #944
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Heatmap converter #944
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you very much! The feature looks very promising.
I haven't looked through the logic yet, just a few overall comments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for addressing my previous comments. I looked a bit deeper and added a few more questions/comments. Not deep enough yet to comment on the algorithm itself :)
Please, rebase the PR on top of the current master, otherwise, while testing the converter I get errors that have been already fixed. Thank you.
| state.methodsCache.assignConstantPool(methodRefs, classRefs, symbols); | ||
| } | ||
|
|
||
| public void nextFile() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it really used for multi-file processing? Why not just creating new Heatmaps instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It allows mixing several jfr files into one single heatmap, and sometimes it is very useful.
src/res/heatmap.html
Outdated
|
|
||
| nextSymbol() { | ||
| return this.byteAt(this.pos++); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a verbatim copy of nextInt6. Maybe, add nextBase123 instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, looks strange) Maybe somebody else took my body to code this peace)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
| return this.nextInt6() | this.nextInt6() << 6 | this.nextInt6() << 12; | ||
| } | ||
|
|
||
| int30(pos) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of this function, I'd just set pos to the tail of the stream and reuse nextInt30.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think touching pos is a good idea, nice place for bugs.
| let runAgain; | ||
| try { | ||
| runAgain = task.f(); | ||
| } catch (e) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What exception can it be?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bugs only
src/res/heatmap.html
Outdated
| nextTask = 0; | ||
| overflow = true; | ||
| } | ||
| } while (performance.now() - start < 8); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just wondering about this magic value
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Numbers from 4 to 20 work nice)))
Big numbers make UI stuck, low numbers make calculations slow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll make some named constant
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
| private void compressMethods(HtmlOut out, Method[] methods) throws IOException { | ||
| for (Method method : methods) { | ||
| out.write18(method.className); | ||
| out.write18(method.methodName); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, the conversion will fail if there are more than 2^18 methods?
Also, will it be more compact to use varint encoding for classess, methods and locations?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can be more compact, yes, but using var length encoding may lead to extra preprocessing step on the html side. I'll check if it is the case.
But it should be more then 2^18 unique method names (not including classes). Anyway, we don't need to be compact here, but it would be nice to be safe)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
refactored
src/converter/one/jfr/Index.java
Outdated
| if (currentKey == null) { | ||
| break; | ||
| } | ||
| //noinspection unchecked |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an IDE-specific hint. javac will still issue a warning. Please use @SuppressWarnings instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
moreover, it is unneeded in current implementation, fixed
|
There is inconsistency in time formats: 24h format on the top and 12h format on a tooltip. Can it be always 24h? |
|
Thank you very much for your review. I'll fix the bugs with canvas (looks like it happened after merging dev on some point). |
|
Heatmap rendering bugs fixed as well |
|
Hello! I tried to test heatmap, and it works nice. But when i tried to merge JFR's and convert it ho heatmap, i stuck on exception: $ jdk-21.0.1+12/bin/java -jar jfr-converter.jar -o heatmap /tmp/file.jfr /tmp/test.html
Converting file.jfr -> test.html Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
at one.convert.JfrConverter.convertJavaClassName(JfrConverter.java:139)
at one.heatmap.SymbolTable.convertClassName(SymbolTable.java:157)
at one.heatmap.SymbolTable.orderedKeys(SymbolTable.java:147)
at one.heatmap.MethodCache.orderedSymbolTable(MethodCache.java:157)
at one.heatmap.Heatmap.evaluate(Heatmap.java:72)
at one.heatmap.Heatmap.dump(Heatmap.java:89)
at one.convert.JfrToHeatmap.dump(JfrToHeatmap.java:70)
at one.convert.JfrToHeatmap.convert(JfrToHeatmap.java:81)
at Main.convert(Main.java:60)
at Main.main(Main.java:46)More details here. |
|
@rus-99-pk pls, provide original jfrs and the merged one |
|
@Artyomcool, was send at upload@profiler.tools. |
|
@rus-99-pk fixed |
Signed-off-by: Artyom Drozdov <artyomd@lightrun.com>
|
@rus-99-pk since you are voluntarily testing the feature, be aware, the very critical bug was fixed with the last commit |
# Conflicts: # src/converter/one/convert/JfrConverter.java
Technically, we could use 0 on the encoder side, but by passing -1 we can distinguish frames with no line info provided and line info irrelevant.


This PR adds Heatmap html file format to async-profiler converters collection.
More about heatmaps: https://www.brendangregg.com/heatmaps.html
This version simpler, but slower, then our previous one: https://github.com/Artyomcool/async-profiler/tree/heatmap
Basically, I've removed all "optimizations" (dirty hacks) from JFRReader, some of which had potential issues.