Instrumenting Android
There are multiple ways to use the profiler with Android. There is the “Java” profiler feature (via about:profiling), which enables profiling for JVM code. This is most likely turned on already for the preset if you are profiling an Android device.
In addition to sampling, markers can be created to specifically mark an instant in time, or a duration. This can be helpful to make sense of a particular piece of the front-end, or record events that normally wouldn’t show up in samples.
Note
This guide explains Android markers in depth. To learn more about how to add a marker in C++, JavaScript or Rust, please take a look at their documentation in Markers, Instrumenting JavaScript or Instrumenting Rust respectively.
Markers in the GeckoView Java codebase
If you are in the GeckoView codebase, then you should have access to ProfilerController
.
See the ProfilerController Java file (javadoc) to find which methods you can use to
instrument your source code.
Here’s an example:
// Simple marker
ProfilerController.addMarker("Marker Name");
// Simple marker with additional information
ProfilerController.addMarker("Marker Name", "info");
// Duration marker
Double startTime = ProfilerController().getProfilerTime();
// ...some code you want to measure...
ProfilerController.addMarker("Marker Name", startTime);
// Duration marker with additional information
ProfilerController.addMarker("Marker Name", startTime, "info");
There are various overloads of addMarker
you can choose depending on your need.
If you need to compute some information before adding it to a marker, it’s
recommended to wrap that code with a isProfilerActive
if check to make sure
that it’s only executed while the profiler is active. Here’s an example:
if (ProfilerController.isProfilerActive()) {
// Compute the information you want to include.
String info = ...
ProfilerController.addMarker("Marker Name", info);
}
Markers in the Fenix codebase
If you are working on Fenix, you can still use the ProfilerController
similar to how
you would you use it in GeckoView.
In addition to the ProfilerController
, you can also use the Profiler.kt
helper class
which also supports adding method Trace markers in the same places you where you would
use the helper class while running a profileable version of the app.
The helper class is useful when you want to add multiple markers in the same class without needing to reference the same marker name everywhere to get all the markers in the same track.
import mozilla.components.support.base.profiler.Profiler
class MyApplication {
val profiler = Profiler("MyApplication")
override fun onCreate() {
profiler.mark("init started")
}
fun importantWork() {
profiler.mark("important work started")
}
}
Similarly, you can add a duration marker as well that allows you to wrap your logic but also return a return for the rest of your application code:
import mozilla.components.support.base.profiler.Profiler
class MyApplication {
val profiler = Profiler("MyApplication")
override fun onCreate() {
profiler.mark("init started")
val result = profiler.markInterval("info") {
importantWork()
}
processResultFromWork(result)
}
fun importantWork(): Int {
return 42
}
}