[00:00.000 --> 00:13.160] Hello, everyone. [00:13.160 --> 00:23.400] And now we have a talk by Johannes Bergberg, I hope you pronounce that right, is a JVM [00:23.400 --> 00:29.720] developer working on profiles and the underlying technology, it currently works on the GAP, [00:29.720 --> 00:34.440] modeling documentation, smaller utilities, and the Firefox profiler. [00:34.440 --> 00:39.880] It's going to have a talk on Firefox profilers beyond the web, using Firefox profiler to [00:39.880 --> 00:45.160] view Java profiling data, and yes. [00:45.160 --> 00:51.200] Yeah, thanks for the kind introduction, yes, I'm Johannes Bergberg, I'm working at the [00:51.200 --> 00:59.320] sub machine team at SAP, we create the best JDK, so just download it, but I'm here because [00:59.320 --> 01:08.520] I worked on the Firefox profiler in the recent months, and yeah, I'm going to start now, [01:08.520 --> 01:13.960] because when I'm telling people that I'm like working at SAP at Firefox profilers, [01:13.960 --> 01:19.120] they first start me two questions, like first, wait, SAP does open source? [01:19.120 --> 01:25.480] Yes, SAP does open source, and quite a lot, for example, here at sub machine, my team [01:25.480 --> 01:32.560] we're working on the open JDK, for example, if you've ever used JDK 17, we have the JDK [01:32.560 --> 01:41.760] 17 maintainer in our team, so we do many nice projects in this field, SAP also works with [01:41.760 --> 01:48.520] the Eclipse Foundation or other parts, so yeah, we're doing quite a bit of open source, [01:48.520 --> 01:56.360] but how did I end up here talking to you in this Mozilla death room as a JDK developer, [01:56.360 --> 02:02.840] which normally doesn't happen, so I had a problem, I had a project on debugging last [02:02.840 --> 02:08.720] year, so what I wanted to do essentially is that I had on the one hand my IDE, and on [02:08.720 --> 02:16.480] the other hand the JVM, they wanted to improve the protocol in between, so I had then some [02:16.480 --> 02:21.880] test cases and some of these, some integration testing, for example, here they parsed some [02:21.880 --> 02:28.720] program and I did something with it, and I wanted to see why it was slower than I expected, [02:28.720 --> 02:35.400] and so what I wanted to do is just write plug on my IDE, tell it that, hey, profile it and [02:35.400 --> 02:40.920] show me the profile, and that's all, and I wanted to do it with open source source, because [02:40.920 --> 02:47.760] I like open source and that our team open source is really key, so I didn't find anything, [02:47.760 --> 02:55.040] but I found some tools that got into this direction, so essentially there were tools [02:55.040 --> 03:02.960] that produced some flame troughs, STUI, and Mario Fusco set a few days back, a lot of [03:02.960 --> 03:08.960] frame graphs, when you do something stupid it punches you in your face and it's impossible [03:08.960 --> 03:15.680] not to see it, so that's great, you can use flame troughs for a lot of things, but sometimes [03:15.680 --> 03:20.840] they are not enough, so when you regard visualizations you have those easy tools that are easy to [03:20.840 --> 03:25.000] use, but don't have that many features, and on the other hand you have the big tool, it's [03:25.000 --> 03:32.400] called JMC, there's lots of features, but has a quite steep learning curve, so I had [03:32.400 --> 03:36.640] to write my own, because I wanted to have something with more visualizations than just [03:36.640 --> 03:43.400] flame troughs, but that was usable, also usable to the end user, and not just the OpenJD [03:43.400 --> 03:51.360] developer like JMC is, quite frankly, and I wanted to just right click on a method, [03:51.360 --> 03:58.080] on the test method, and just tell my IDE, hey, run the thing, so I don't end up writing [03:58.080 --> 04:06.920] so much code and boilerplate, so writing your own intelligent plugin, and that's the IDE [04:06.920 --> 04:12.000] I'm targeting, but it's quite the same for all the IDEs too, like visual studio code, [04:12.000 --> 04:19.040] is quite simple, you can just download some templates and work on them, so this I did [04:19.040 --> 04:25.680] like in August in like half a week, but then it came to visualization options, so I looked [04:25.680 --> 04:30.600] around and thought, maybe creating my own visualizations like flame troughs and so on, [04:30.600 --> 04:38.520] but this turned out to be cumbersome, and really would take a lot of work, so I looked [04:38.520 --> 04:45.920] around for web-based visualizations, because you can just embed a web-based profiling view [04:45.920 --> 04:51.480] into your IDE, because for example in Telstra you have a chromium, an embedded chromium, [04:51.480 --> 04:55.880] and in VS code it's essentially a browser anyway, so that's no problem, iPhone speed [04:55.880 --> 05:01.800] scope, which is quite nice, but the problem is it doesn't show anything other than stack [05:01.800 --> 05:07.040] traces and some profile timing information, and I wanted to show more, there is kind of [05:07.040 --> 05:11.920] an existing plugin for IntelliJ, but that only shows flame grouse, and so we're back [05:11.920 --> 05:19.000] to step one, and then I found Firefox profile, and this is how I ended up here, so essentially [05:19.000 --> 05:24.000] Firefox profile is this large application that you've probably seen in some other talks [05:24.000 --> 05:32.200] today too, this is actually taken from a previous talk, because I was too lazy to run Firefox [05:32.200 --> 05:40.080] profile, directly you see here it's like it does everything, and it's quite cool, and [05:40.080 --> 05:46.920] one of the many advantages is that it's developed by a small team that answer even stupid questions [05:46.920 --> 05:53.520] in a matrix channel, so check it out if you have some questions, and they were open to [05:53.520 --> 06:01.400] working with me on my project, and also it's backed by cooperation, it's backed by Mozilla, [06:01.400 --> 06:09.880] which is quite cool, because it's not a one-man project like other tools are, and so what did [06:09.880 --> 06:15.920] I do to integrate it, and what might you do if you want to also use Firefox profile, [06:15.920 --> 06:23.320] it essentially points down to creating a converted to my data format, it's the JFR file format [06:23.320 --> 06:28.760] to the Firefox profile format, and then you put it in the server, because Firefox profile [06:28.760 --> 06:36.560] likes it when you can just say take this file from a URL, so you put it in the server, that's [06:36.560 --> 06:42.680] fine, for me I created a travel in server, then you can just wrap it in IntelliJ plugin [06:42.680 --> 06:54.840] or use code plugin or zone, and then I took the Firefox profile UI, you can use profile.firefox.com, [06:54.840 --> 06:58.880] but you would typically just host it your own, because Daniel Burke's in demos like [06:58.880 --> 07:05.640] Bolly today, when I have time, and you can control all the changes that come into your [07:05.640 --> 07:12.920] Firefox profile UI, and also you can use a modified version, which I did to put all [07:12.920 --> 07:17.840] my progress that is still out there and not merged into one version, so the things you [07:17.840 --> 07:26.080] later see, that the inmate will sometimes not yet in the mainstream Firefox profile, [07:26.080 --> 07:33.560] so shortly to the file format, so file format is quite simple, it's just a chasing file, [07:33.560 --> 07:40.200] and this is zipped, and it has some metadata information like the name, the interval, some [07:40.200 --> 07:46.800] settings, and then you have the stretch information, so for every thread you have a separate section [07:46.800 --> 07:52.320] in the profile file, and you have a list of samples there, and this list contains essentially [07:52.320 --> 07:59.480] the time of when the sample is taken, the stack, and the CPU delta that elapsed the [07:59.480 --> 08:05.600] CPU time since the last sample, so it can be used to show the CPU usage data, then the [08:05.600 --> 08:13.080] stack is not all the stack, but it's an index into the stack area, and this contains like [08:13.080 --> 08:22.200] the list of stacks, and where the stack is just a frame appointed to the previous stack, [08:22.200 --> 08:26.160] like the top frame, and then the previous stack, so it points back, and then the category, [08:26.160 --> 08:31.640] and of course the frame is an index into the frame area, and that contains the functional [08:31.640 --> 08:38.240] line, so what you need for a frame, and then of course function is not really the function, [08:38.240 --> 08:43.880] but it's an index into the functions area, and you get the point here, because name and [08:43.880 --> 08:50.720] file are of course not strings, but they are indexes into the string table, that's quite [08:50.720 --> 08:57.440] hard to debug sometimes, and I had many struggles with it, but it's quite performant, and it's [08:57.440 --> 09:05.240] easy for the frontend to see, so after I explain to you how I did it, here's the plugin, I [09:05.240 --> 09:12.680] call the Java JVR profile plugin, you can find it in the track branch marketplace on [09:12.680 --> 09:21.040] GitHub, it's open source, it's MIT license, I believe, and it works because JVR was open [09:21.040 --> 09:30.240] sourced with JDK 11, so it's all open source, just try it out, so how can you get it, just [09:30.240 --> 09:39.640] open your IDE, and go into the plugin install, view and type in Java JVR profile, and you [09:39.640 --> 09:49.640] get it, then you get some nice buttons, when you right click, and you can just click on [09:49.640 --> 09:57.280] the profile with JVR, then you profile it, and then here's a simple example application [09:57.280 --> 10:02.480] that just computes kind of complicated, a few nuchin number or something like that, [10:02.480 --> 10:09.240] and then you can see that it executes the program with some JVR-related options to [10:09.240 --> 10:17.920] profile it, and then it automatically the profile of JVR-file, you get the call tree, [10:17.920 --> 10:24.880] you can also look at how every frame is like executed, whether it's in interpreted mode [10:24.880 --> 10:31.600] or in our JIT compile, then you can double click and jump back to the IDE, so it has [10:31.600 --> 10:39.200] basic IDE integrations, and you can shift double click and see the source view that was presented [10:39.200 --> 10:45.040] in the previous talk shortly, so you can see here that in this code, the recursive call [10:45.040 --> 10:51.480] is called the most, it's found the most time in the static calls, and then you can have [10:51.480 --> 10:58.880] a function table which lists all the methods combined, so from all the stack traces and [10:58.880 --> 11:06.680] you see what method is used the most, that's not yet in the mainline Firefox Profiler, [11:06.680 --> 11:16.880] you can have some flame crafts, and you can have some nice tooltips, and you can get some [11:16.880 --> 11:24.600] information on the profile, you can even upload it like a normal Firefox profile, so you can [11:24.600 --> 11:32.840] share these profiles and view them in a normal profile at Firefox.com, just with some few [11:32.840 --> 11:40.720] features, and then we can also open any JVR-file, and JVR is like the default, like the de facto [11:40.720 --> 11:46.760] standard for profiling files in Java, and you can see here that we get also some crafts [11:46.760 --> 11:54.840] that show us the CPU load and give us some summary on GC, like how much memory it requested, [11:54.840 --> 12:00.040] and what's also cool, we can not only see timing, but we can also see call tree for [12:00.040 --> 12:04.960] other things, like for Java error, for thread starts, where did they happen, or for object [12:04.960 --> 12:14.240] allocation, and when you get to Java error, you see that this code uses error to create [12:14.240 --> 12:22.760] error every time, like probably the parsing fails, so we can also see, as the last part, [12:22.760 --> 12:29.480] the market chart, so we can get all the events that the JVM remits, so for example, we see [12:29.480 --> 12:43.720] here at the top, that we had a drop in the memory that the heap was large, and we investigated, [12:43.720 --> 12:49.800] we could zoom in and see, okay, that's probably because here GC happened, and this GC took [12:49.800 --> 12:54.960] like 10 milliseconds, and this is quite nice because you can then investigate, have the [12:54.960 --> 13:02.560] call tree as a simple thing, and then later drop in and go deep dive into the data, and [13:02.560 --> 13:08.640] if you know Async Profile, it also supports Async Profile, and also when you want to create [13:08.640 --> 13:17.080] the profile, you can decide where you want JVR to build in for the JDK or Async Profile, [13:17.080 --> 13:26.240] and that's all, but I think I still have some time, so I hope this works, because I can [13:26.240 --> 13:31.720] tell you a lot that it might work, and we can show you some screens, but here is the [13:31.720 --> 13:37.080] actual working, hopefully working prototype, so just right click on the main method, tell [13:37.080 --> 13:46.440] it Profile with JVR, and then it tells you, hey, I profiled it, then it opens the profile, [13:46.440 --> 14:01.200] and then you can just look at it, zoom around, and see that you have to select the main JVR, [14:01.200 --> 14:06.480] you can jump back to the source code, you can shift, double click, and everything, and [14:06.480 --> 14:12.920] the cool thing is you can even open, as I showed you, arbitrary JVR files, they shouldn't [14:12.920 --> 14:20.120] be too large, because then my program runs out of memory sometimes, it's still a prototype, [14:20.120 --> 14:30.280] so try it if you want, I would be happy to have any feedback, go to the issue pages, [14:30.280 --> 14:36.680] and eventually you find this plug-in, as I said, in the chat print marketplace, you [14:36.680 --> 14:43.000] find me on Mastodon, on Twitter, and on GitHub, but you also find the subprojects, so you [14:43.000 --> 14:50.080] can use parts of this project, like only the converter, and only the JVR to Firefox Profile [14:50.080 --> 14:59.200] server, you find more information on my tool, and also a background information to this [14:59.200 --> 15:06.640] talk, in two blog posts on my blog, and you can find the submachine team at Sweet Submachine [15:06.640 --> 15:24.120] at Twitter, and find out about our great projects at Submachine.io, that's for me, thanks. [15:24.120 --> 15:34.720] Thank you very much, and we have quite a bit of time for questions, so... [15:34.720 --> 15:35.720] Thank you. [15:35.720 --> 15:41.840] Have you received any feedback from users about this tool, like some colleagues or...? [15:41.840 --> 15:48.000] Yes, good questions, yeah, I received quite some feedback on Twitter, they were quite [15:48.000 --> 15:55.440] happy, I did some internal... I showed it internally at SAP, to some colleagues, and [15:55.440 --> 16:01.920] they were quite happy, I also showed it to friends of mine, and also it was quite great. [16:01.920 --> 16:08.600] It still has, of course, problems, because it's a prototype, not everything might work, [16:08.600 --> 16:13.440] but yeah, I'm looking forward, so just give it a try, it's free, it's open source, open [16:13.440 --> 16:18.360] some issues on GitHub, if you like, so yeah. [16:18.360 --> 16:20.400] I will steal the mic. [16:20.400 --> 16:25.640] Did you add to forward some patches upstream to make it work in the first place? [16:25.640 --> 16:27.280] Yes, a lot, so for example... [16:27.280 --> 16:31.800] Because you mean they have bugs, or you need to adjust it for the... [16:31.800 --> 16:40.480] There for example, this feature here is not yet in Master, but for example, what I added [16:40.480 --> 16:47.200] was, you saw this, this, you saw this here, this, the listing of the categories, this [16:47.200 --> 16:53.760] is something that I added, and I added pull requests for the function table, which is [16:53.760 --> 17:01.320] not yet in because it's far more work, I added some resizing and searching, that's yet, that's [17:01.320 --> 17:07.360] I think in, so I added some pull requests that are in, but not all of them, but I hope [17:07.360 --> 17:10.640] I get it in in the next few months. [17:10.640 --> 17:14.640] You can give beer to the upstream developers that are here to get the patch. [17:14.640 --> 17:20.880] Yeah, but I fixed all the bugs that they wanted to be fixed, so I think we're working [17:20.880 --> 17:21.880] more like colleagues. [17:21.880 --> 17:23.360] I will ask a follow-up question quickly. [17:23.360 --> 17:30.040] Did you have to do anything Java specific in that case? [17:30.040 --> 17:37.320] There's nothing that is real on Java specific, so the only the converters like Java specific [17:37.320 --> 17:51.360] because it takes Java data and processes it, but anything else in the UI is generic. [17:51.360 --> 18:00.120] I was wondering if this could be useful to profile Java applications that run native [18:00.120 --> 18:04.280] code and the other way around, and how would that work? [18:04.280 --> 18:12.640] Speaking of, for example, Firefox 400, I don't think we have a lot of insight into the performance [18:12.640 --> 18:16.520] of our Java code, and that would be useful to have. [18:16.520 --> 18:22.000] So, it's in some ways where they can work with chain I or something like that. [18:22.000 --> 18:29.800] I think asking profile is a quite nice profile that I also support, and this gives you information [18:29.800 --> 18:38.480] on native, on native phrases, and I'm working on getting a profiling API into OpenJK that [18:38.480 --> 18:44.200] improves this a lot, but if you want to know more about the struggles, come tomorrow to [18:44.200 --> 18:52.280] my talk in the Fuji room, they hear enough about this topic. [18:52.280 --> 18:53.280] Hi. [18:53.280 --> 18:58.040] Yeah, thanks for the presentation, very impressive. [18:58.040 --> 18:59.960] The question I had, actually, I have two questions. [18:59.960 --> 19:07.480] The first one is, what is about Firefox profiler that made you choose it, I suppose, and then [19:07.480 --> 19:17.760] the second question is, do you see the potential for maybe a tool like this to have a web-based [19:17.760 --> 19:18.760] editor? [19:18.760 --> 19:23.520] Yes, the first thing, why did I choose it? [19:23.520 --> 19:28.240] Because it's a nice project and I didn't want to write everything on my own, and it contained [19:28.240 --> 19:33.160] lots of the features that I already wanted, so, yeah, and they could ask questions, because [19:33.160 --> 19:38.040] when you're working alone on such a prototype is that you don't get any feedback. [19:38.040 --> 19:45.160] Here I got a lot of feedback on progress, and it was a quite good learning experience. [19:45.160 --> 19:51.880] The other thing is, yeah, as I said, the project consists only of a tiny intelligent [19:51.880 --> 19:57.120] wrapper around the other code, and this can be used to just integrate it into your Spring [19:57.120 --> 20:02.200] web app to directly show it in the web. [20:02.200 --> 20:10.400] I have some ideas on this, just follow my blog to know more about this, or my Twitter [20:10.400 --> 20:19.320] almost. [20:19.320 --> 20:21.840] So do you think about the upload local profile? [20:21.840 --> 20:25.360] Is this an important feature in your opinion? [20:25.360 --> 20:31.680] Is it something that you'll, is it part of the features that made you choose Firefox [20:31.680 --> 20:32.680] profile? [20:32.680 --> 20:36.720] Yeah, it's quite a great feature, because you can essentially, in open source, you could [20:36.720 --> 20:43.960] later than just tell other people, I have some performance issue here, for example, [20:43.960 --> 20:44.960] for issues. [20:44.960 --> 20:52.440] It's essentially the same thing Mozilla does, and I hope I can open it to use it in a corporate [20:52.440 --> 21:02.200] setting, for example, adding features to use Microsoft Thrive for it, so it's more safe, [21:02.200 --> 21:06.240] because currently you're uploading it into the web, and that's not that great when you're [21:06.240 --> 21:08.840] doing internal company stuff. [21:08.840 --> 21:14.080] But this feature then could really make it easy for people to just say, hey, here I have [21:14.080 --> 21:21.400] some problem, give me your stack trace, just upload it, and you're fine. [21:21.400 --> 21:26.440] So maybe next feature could be a server, and make it configure. [21:26.440 --> 21:33.880] The problem is, it's just me currently working on it, and so it's just a prototype, I have [21:33.880 --> 21:39.320] to see what could be implemented in the future. [21:39.320 --> 21:41.720] Any other questions? [21:41.720 --> 21:47.000] We still have three minutes, so if you have questions, we can take them. [21:47.000 --> 21:53.920] Thank you very much, do you want to add anything else? [21:53.920 --> 22:00.040] Just try it out, I would like to have some users, because I want to know what features [22:00.040 --> 22:04.880] are important to you, and also where you find some problems, for example, someone found [22:04.880 --> 22:11.840] that the Microsoft support wasn't there, so on Microsoft it just crashed, on Windows, [22:11.840 --> 22:19.280] so if you find any issues, please drop by, and come to the Matrix channel of the Firefox [22:19.280 --> 22:26.240] profile, there you can find me sitting around all day, and can also answer questions directly [22:26.240 --> 22:27.240] on it. [22:27.240 --> 22:28.240] Thank you very much. [22:28.240 --> 22:35.240] Thank you very much.