Update intermittent_memory_spike.md
authorMario Hewardt <marioh@microsoft.com>
Thu, 9 May 2019 20:31:24 +0000 (13:31 -0700)
committerGitHub <noreply@github.com>
Thu, 9 May 2019 20:31:24 +0000 (13:31 -0700)
documentation/tutorial/intermittent_memory_spike.md

index db13bd380f23f6e3b8e3fabb3da98dfb79494291..481c9d453c1200f1e790160d947cad0688b5f9f6 100644 (file)
@@ -4,12 +4,12 @@
 
 http://localhost:5000/api/diagscenario/memspike/{seconds}
 
-In this scenario, the endpoint will experience intermittent memory spikes over the specified number of seconds. Memory will go from base line to spike and back to baseline a number of times. What makes this scenario different from the memory leak scenario is that we will have to figure out a way to automatically trigger the collection of a dump when the memory spikes. 
+In this scenario, the endpoint will experience intermittent memory spikes over the specified number of seconds. Memory will go from base line to spike and back to baseline several times. What makes this scenario different from the memory leak scenario is that we will have to figure out a way to automatically trigger the collection of a dump when the memory spikes. 
 
 ### Memory counters
-Before we dig into collecting diagnostics data to help us root cause this scenario, we need to convince ourselves that what we are actually seeing is an intermittent memory spike. To help with this we can use the dotnet-counters tool which allows us to watch the memory usage for a selected dotnet process (please see 'Installing the diagnostics tools' section). 
+Before we dig into collecting diagnostics data to help us root cause this scenario, we need to convince ourselves that what we are  seeing is an intermittent memory spike. To help with this we can use the dotnet-counters tool which allows us to watch the memory usage for a selected dotnet process (please see 'Installing the diagnostics tools' section). 
 
-Let's run the webapi (dotnet run) and before hitting the above URL (specifying 300 seconds), lets check our managed memory counters:
+Let's run the webapi (dotnet run) and before navigating to the above URL (specifying 300 seconds) check our managed memory counters:
 
 > ```bash
 > dotnet-counters monitor --refresh-interval 1 -p 4807
@@ -23,7 +23,7 @@ The output should be similar to the below:
 
 Here we can see that right after startup, the managed heap memory is 4MB. 
 
-Now, let's hit the URL (http://localhost:5000/api/diagscenario/memspike/300) which will run for 5 minutes giving us ample time to experiement. 
+Now, let's hit the URL (http://localhost:5000/api/diagscenario/memspike/300) which will run for 5 minutes giving us ample time to experiment. 
 
 Re-run the dotnet-counters command. We should see an alternating heap size with a baseline of roughly 250MB and the highest spike around 530MB. The memory usage will alternate between baseline and spike every 5 seconds or so. 
 
@@ -33,25 +33,25 @@ Baseline:
 High:
 ![alt text](https://user-images.githubusercontent.com/15442480/57338164-36272b80-70e1-11e9-843a-604af1ddfd5f.jpg)
 
-At this point, we can safely say that memory is spiking to a high that is not normal and the next step is to to run a collection tool that can help us collect the right data for memory analysis at the right time. 
+At this point, we can safely say that memory is spiking to a high that is not normal and the next step is to run a collection tool that can help us collect the right data for memory analysis at the right time. 
 
 
 ### Core dump generation
 Let's step back a bit and revisit the high memory scenario earlier in the tutorial. In that scenario, memory grew high and stayed high allowing us the opportunity to run the dotnet-dump command without restriction. However, in our current scenario we have a short memory spike that only lasts about 5 seconds per spike. This makes it difficult to get setup to run the dotnet-dump tool manually. What we would preferably like is a tool that could monitor the dotnet core counters and automatically create a core dump once a threshold has been breached. This is a perfect opportunity to start exploring how we can write our own diagnostics tools to cater to our diagnostics needs. 
 
-What we would like this tool to do do is allow the user to specify the pid of the target process as well as the threshold in memory consumption (in MBs). It would then continously monitor the process and create a dump if the threshold is breached:
+What we would like this tool to do is allow the user to specify the pid of the target process as well as the threshold in memory consumption (in MBs). It would then continuously monitor the process and create a dump if the threshold is breached:
 
 > ```bash
 > sudo ./triggerdump <pid> <memory threshold in MBs>
 > ```
 
 #### Some background before we start writing the tool...
-The dotnet core runtime contains a mechanism known as the EventPipe and serves as a mechanism to push events to interested consumers. There are a number of different events that flow through the EventPipe including diagnostics information such as counters. The EventPipe is exposed as a Unix domain socket on Linux machines and named pipes on Windows.  EventPipe is set to duplex mode which means that clients can both read and write to the pipe. A diagnostics application can register to consume these events from the EventPipe and create new diagnostics experiences. Rather than communicating directly with EventPipe there is a client library that can be used and implemented in Microsoft.Diagnostics.Tools.RuntimeClient.dll.
+The dotnet core runtime contains a mechanism known as the EventPipe and serves as a mechanism to push events to interested consumers. There are several different events that flow through the EventPipe including diagnostics information such as counters. The EventPipe is exposed as a Unix domain socket on Linux machines and named pipes on Windows.  EventPipe is set to duplex mode which means that clients can both read and write to the pipe. A diagnostics application can register to consume these events from the EventPipe and create new diagnostics experiences. Rather than communicating directly with EventPipe there is a client library that can be used and implemented in Microsoft.Diagnostics.Tools.RuntimeClient.dll.
 
-Events that are written to the EventPipe can come from multiple sources (or providers) and as such, clients that recieve events over EventPipe can filter those events based on specific providers.  
+Events that are written to the EventPipe can come from multiple sources (or providers) and as such, clients that receive events over EventPipe can filter those events based on specific providers.  
 
 #### Writing the tool...
-We have two requirements in order to implemented a tool that will create a dump file based on memory consumption:
+We have two requirements in order to implement a tool that will create a dump file based on memory consumption:
 
 * Being able to read dotnet memory counter to know when it breaches the specified threshold
 * Generate the actual core dump
@@ -64,7 +64,7 @@ CounterProvider provider=null;
 KnownData.TryGetProvider("System.Runtime", out provider);
 string prov = provider.ToProviderString(1); 
 ```
-The above code attempts to get the System.Runtime provider which we will need in the next section of code that actually configures and starts the counter collection:
+The above code attempts to get the System.Runtime provider which we will need in the next section of code that configures and starts the counter collection:
 
 ```csharp
 Task monitorTask = new Task(() => 
@@ -103,7 +103,7 @@ private static void Dynamic_All(TraceEvent obj)
     }
 }
 ```
-Every time the callback is invoked, a TraceEvent is recieved. The TraceEvent contains information about the event that was delivered. In our case, the first thing we do is to make sure the event corresponds to EventCounters. If so, we get the GC Heap Size counter from the event payload and compare it to the threshold that the user set as part of the command line invocation. If the threshold was breached we are ready to generate a dump. 
+Every time the callback is invoked, a TraceEvent is recieved. The TraceEvent contains information about the event that was delivered. In our case, the first thing we do is to make sure the event corresponds to EventCounters. If so, we get the GC Heap Size counter from the event payload and compare it to the threshold that the user set as part of the command line invocation. If the threshold was breached, we are ready to generate a dump. 
 
 The last step of the puzzle is to generate the dump. For brevity, we will focus only on core dump generation on Linux. In preview 5, the way to generate a core dump is to invoke the createdump tool that ships with the runtime. Add the following code to the Dynamic_All method (replacing the Generate dump and exit comment):