Control Profiling Session with API
The profiling API provides a number of classes which allow you to control the profiling process. For example, right from the code of your application, you can:
get a memory snapshot:
MemoryProfiler.GetSnapshot()
,enable or disable collecting memory allocation data:
MemoryProfiler.CollectAllocations(bool enable)
,and even force garbage collection:
MemoryProfiler.ForceGc()
,
For the detailed information about the API classes, refer to API Reference.
There are two main scenarios that require using the profiling API:
Note that in this case you must use the separate self-profiling API.
Profiling a specific part of the code
The API allows you to narrow the analysis scope and profile only the code you are interested in. For example, sometimes, it is not that easy to click the Get Snapshot button at the right moment. With the profiling API, you can do a "get a snapshot" call at an exact point of your code.
Note that dotMemory 2018.3 and earlier used another version of the profiling API (for the details on this API, refer to the dotMemory 2018.3 documentation ). This API is still supported but we strongly recommend that you use the latest API version described in this section.
Main concepts:
The source code of the API is available on GitHub. The code is distributed under Apache license.
The profiling API is distributed as a JetBrains.Profiler.API NuGet package which you should reference in your project.
To enable the API, you must start a profiling session with the enabled How to control profiling | Using API parameter in the profiler options.
When using the API, the only difference comparing to a normal profiling session is in how you control the session: instead of clicking the buttons in the profiling controller, you call the corresponding API methods.
If you run your application with no profiling, the calls to the API methods will be ignored. The API will not throw any errors.
The main class you should use to control a profiling session is the
MemoryProfiler
static class.To get a memory snapshot and save it to the disk, call
MemoryProfiler.GetSnapshot()
– an equivalent to pressing the Get Snapshot button in the profiling controller.To enable/disable collecting memory allocation data, call
CollectAllocations(bool enable)
– an equivalent to pressing the Collect Allocations button.To check whether a
CollectAllocations(bool enable)
call will have effect, useMemoryProfiler.GetFeatures()
. Note that this check is not obligatory.
To use the API for profiling a specific part of the code
Reference the
JetBrains.Profiler.API
NuGet package in your project.Insert calls to methods of the
MemoryProfiler
class into your code as required by your use case. For example:private void SomeMethod() { // Enable collecting memory allocation data MemoryProfiler.CollectAllocations(true); ...// Here goes some code that I want to profile // Get a snapshot MemoryProfiler.GetSnapshot(); }Start profiling the application from dotMemory, and select the How to control profiling | Using API parameter in the profiler options.
Self-profiled applications
As the name suggests, in this scenario, an application profiles itself. The main difference comparing to the previous scenario is in how you initiate profiling. If you profile a specific part of the code using the profiling API, you initiate a session manually (for example, using the dotMemory UI). In case of a self-profiled application, the session is initiated right from the application code.
For example, ReSharper uses this API to collect statistics about how it behaves on end-user desktops. When a user faces a performance or memory issue, the support team asks the user to run ReSharper with a special option (it enables the self-profiling feature) and reproduce the issue. The collected snapshot is then sent to the development team.
Main concepts:
The self-profiling API is a separate JetBrains.Profiler.SelfApi NuGet package which you should reference in your project.
To control the profiling session, the API uses the dotMemory.exe command-line tool.
The dotMemory.exe tool is not a part of the package. When you initialize the API using the
DotMemory.EnsurePrerequisite()
method, the API downloads the latest version of the JetBrains.dotMemory.Console NuGet package.By default, the tool from the package is saved to the %localappdata%\JetBrains\Profiler folder. To specify another location, use the
downloadTo
argument of theDotMemory.EnsurePrerequisite()
method.If the package with the dotMemory.exe tool already exists, the new one is not downloaded.
To get a single snapshot, use the
DotMemory.GetSnapshotOnce()
method.To get multiple snapshots, you should:
attach to the current process using
DotMemory.Attach()
get any number of snapshots using
DotMemory.GetSnapshot()
detach from the process using
DotMemory.Detach()
To configure a profiling session, for example, specify the path for saved snapshots, you must use an instance of the
DotMemory.Config
class.You can use the self-profiling API simultaneously with the profiling API.
The resulting self-profiling snapshot has the
.dmw
file extension (it is actually a dotMemory workspace ).
To add self-profiling to an application
Reference the
JetBrains.Profiler.SelfApi
NuGet package in your project.Initialize the self-profiling API by calling the
DotMemory.EnsurePrerequisite()
method. Note that the first initialization may take some time as the API needs to download the dotMemory.exe command-line tool. If you want to track the downloading process and have the ability to cancel it, use theDotMemory.EnsurePrerequisitesAsync()
method directly. It lets you useCancellationToken
and track progress using a callback variable.Add API calls as required by your use case:
If you need only one snapshot:
static void Main(string[] args) { ... // Here goes some init code // Initialize the API and download dotMemory.exe (if needed) DotMemory.EnsurePrerequisite(); SomeMethod(); } private void SomeMethod() { ... // Here goes some code that I want to profile // Get a snapshot and save it to Temp var config = new DotMemory.Config(); config.SaveToDir("C:\\Temp\\Workspace"); DotMemory.GetSnapshotOnce(config); }If you need more than one snapshot:
static void Main(string[] args) { ... // Here goes some init code // Initialize the API and download dotMemory.exe (if needed) DotMemory.EnsurePrerequisite(); // create profiling config and attach to the current process var config = new DotMemory.Config(); config.SaveToDir("C:\\Temp\\Workspace"); DotMemory.Attach(config); SomeMethod(collection); // Detach from the current process DotMemory.Detach(); } private void SomeMethod(IEnumerable<String> collection) { foreach (var item in collection) { ... // Here goes some code that I want to profile // Get a snapshot DotMemory.GetSnapshot(); } }