Subsystems
The Subsystems filter allows you to quickly evaluate how time in a particular call tree is distributed among various components: user and system code, WPF, LINQ, collections, strings, and more.
How subsystems work
With a few exceptions (refer to Special Subsystems below), each subsystem simply groups calls made within a certain namespace or assembly.
For example, all calls of the methods declared in the WindowsBase
, PresentationCore
and PresentationFramework
assemblies are grouped under the WPF subsystem. The time shown next to WPF in the Subsystems filter is the total time of all these calls for all selected threads.
Subsystem name.
Total time spent in a particular subsystem summed up for all selected threads.
The percentage of time spent in a subsystem relative to the total selected time.
To apply a filter by subsystem
Select the desired subsystem in Subsystems.
After you select a subsystem, other filters will show data only for the time intervals where the selected subsystem has worked.
Special subsystems
Some subsystems are calculated not by grouping calls from particular assemblies and namespaces but based on other data. Note that timeline snapshots provide a wider list of subsystems.
The list of special subsystems:
System code: all source code that doesn't match the rules in the chosen active profile and belongs to standard system libraries.
User code: all source code that doesn't match the rules in the chosen active profile and doesn't belong to standard system libraries.
GC Wait: all time intervals where threads wait for other threads to finish the blocking garbage collection. Note that the GC Wait time is calculated somewhat differently compared to the Garbage Collection event.
JIT: all activities related to JIT compilation. Calculated based on ETW events data (timeline snapshots only).
SQL query: all activities related to communication with SQL server. Calculated based on ETW events data (timeline snapshots only).
File I/O: all activities related to file operations. Note that this subsystem is calculated based not only on file I/O ETW events but also based on grouping calls from the
System.IO
and other namespaces. That is why File I/O subsystem's time may slightly differ from the time of the File Operations event.Waiting for CPU: indicates that a thread is ready to run on the next available CPU core. Typically, these are inevitable pauses related to switching a thread between CPU cores or changing thread state from Waiting to Running. Long Waiting for CPU intervals may mean thread starvation and CPU overload.
Calculated based on ETW events data (timeline snapshots only).
Awaiting Time: (applicable to asynchronous code only) time intervals when async methods wait until their tasks are finished. Learn how to analyze asynchronous code
Lock Contention: takes place when a thread tries to acquire the lock to an object which is already acquired by another thread*. Until the object is released, the thread is blocked (in other words, it is in the Waiting state). In some cases, this may lead to a so-called serial execution which negatively affects application performance. The serial execution pattern can be easily determined using the Threads diagram. Instead of threads running in parallel, you will see only one thread running at a time.
Calculated based on ETW events data (timeline snapshots only).
Configure subsystems
dotTrace lets you create your custom subsystems and group a number of subsystems in profiles.
To add a subsystem
From the main menu, select Options dialog opens.
. TheClick Profiles on the left pane.
Click Create new subsystem on the Profiles pane, then Add empty subsystem.
In the Subsystem definition:
Enter a subsystem name in the Name field.
Choose the appropriate Color.
Clear the Enable subsystem in current profile checkbox, if you want to disable the subsystem in the current profile.
Specify subsystem visibility options:
Show – the subsystem will be shown as a separate entry.
Join – subsystem's time will be calculated within calling subsystems. The subsystem will be shown separately only in case there are no subsystems to join with.
Hide – the subsystem will be hidden. Subsystem's time will be excluded from calculations.
- For example
MethodA
belongs toSubsystemA
and callsMethodB
(belongs toSubsystemB
) which, in turn, callsMethodC
(belongs toSubsystemC
). If all subsystems are set to Show, subsystem times will be calculated as follows:SubsystemA = MethodA
SubsystemB = MethodB
SubsystemC = MethodC
In case you set
SubsystemB
to Join, subsystems will be calculated as follows:SubsystemA = MethodA + MethodB
SubsystemC = MethodC
In case you set
SubsystemB
to Hide, subsystems will be calculated as follows:SubsystemA = MethodA
SubsystemC = MethodC
Click Add and Clean to manage rules. All rules are displayed in the list.
Click OK.
You can also create a subsystem by duplicating an existing one.
To duplicate a subsystem
From the main menu, select Options dialog opens.
. TheClick Profiles on the left pane.
Click Create new subsystem on the Profiles pane, then Duplicate subsystem.
In Subsystem definition:
If necessary, modify the Subsystem name.
Redefine the Color.
Click Add and Clean to manage rules. All rules are displayed in the list.
Click OK.
At any time you can return to existing subsystems and modify rules for them.
After all necessary subsystems are defined, you can tune the settings a bit more. All subsystems that should be taken into account can be gathered in one profile and arranged according to their importance. So a profile is just a set of important or active subsystems. It can have a name or be left unnamed.
If a method matches two rules from different subsystems, dotTrace applies the rule from the subsystem higher than the other one in the subsystem list.
To create a new profile
From the main menu, select Options dialog opens.
. TheClick Profiles on the left pane. A new unnamed profile is created.
Click Add new profile.
Specify a profile name.
In the list of subsystems, configure the set of active subsystems by selecting the corresponding checkboxes.
Optionally, you can reorder the sequence of subsystems with the Move selected subsystem up or Move selected subsystem down buttons.
Click OK.
If you aren't satisfied with the changes you made to the subsystem configuration, you can quickly reset them to factory defaults using the Reset Defaults button.