KEMBAR78
Heatmap converter by Artyomcool · Pull Request #944 · async-profiler/async-profiler · GitHub
Skip to content

Conversation

@Artyomcool
Copy link
Contributor

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.

Copy link
Member

@apangin apangin left a 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.

@Artyomcool Artyomcool requested a review from apangin July 9, 2024 09:24
Copy link
Member

@apangin apangin left a 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() {
Copy link
Member

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?

Copy link
Contributor Author

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.


nextSymbol() {
return this.byteAt(this.pos++);
}
Copy link
Member

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?

Copy link
Contributor Author

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)

Copy link
Contributor Author

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) {
Copy link
Member

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.

Copy link
Contributor Author

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) {
Copy link
Member

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bugs only

nextTask = 0;
overflow = true;
}
} while (performance.now() - start < 8);
Copy link
Member

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

Copy link
Contributor Author

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.

Copy link
Contributor Author

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

Copy link
Contributor Author

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);
Copy link
Member

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?

Copy link
Contributor Author

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)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

refactored

if (currentKey == null) {
break;
}
//noinspection unchecked
Copy link
Member

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.

Copy link
Contributor Author

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

@apangin
Copy link
Member

apangin commented Jul 21, 2024

I noticed on many profiles that a heatmap gets truncated when switching to a larger scale:

E.g., on 1 minute scale, the heatmap ends at 14:19:42
heatmap1

while on 5 minute scale, it ends at 13:19:55
heatmap5

@apangin
Copy link
Member

apangin commented Jul 21, 2024

There is inconsistency in time formats: 24h format on the top and 12h format on a tooltip. Can it be always 24h?
Also, on the top ruler, time is printed in the middle between ticks, so it's unclear which tick it corresponds to.

@Artyomcool
Copy link
Contributor Author

Artyomcool commented Jul 22, 2024

Thank you very much for your review. I'll fix the bugs with canvas (looks like it happened after merging dev on some point).

@Artyomcool
Copy link
Contributor Author

Heatmap rendering bugs fixed as well

@Artyomcool Artyomcool requested a review from apangin August 12, 2024 10:25
@rus-99-pk
Copy link

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.

@Artyomcool
Copy link
Contributor Author

@rus-99-pk pls, provide original jfrs and the merged one

@rus-99-pk
Copy link

@Artyomcool, was send at upload@profiler.tools.

@Artyomcool
Copy link
Contributor Author

Artyomcool commented Sep 20, 2024

@rus-99-pk fixed
Thank you for testing!

@Artyomcool
Copy link
Contributor Author

@rus-99-pk since you are voluntarily testing the feature, be aware, the very critical bug was fixed with the last commit

@apangin apangin merged commit ec83ae6 into async-profiler:master Dec 29, 2024
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants