|
| 1 | +<p> |
| 2 | + The static <code>OS</code> class in the <code>QuantConnect</code> namespace exposes memory and CPU metrics that you can read from your algorithm to monitor resource usage during backtests and live trading. |
| 3 | +</p> |
| 4 | + |
| 5 | +<p>The following table lists the static members of the <code>OS</code> class that report memory and CPU usage:</p> |
| 6 | + |
| 7 | +<table class="qc-table table"> |
| 8 | + <thead> |
| 9 | + <tr> |
| 10 | + <th>Member</th> |
| 11 | + <th>Data Type</th> |
| 12 | + <th>Description</th> |
| 13 | + </tr> |
| 14 | + </thead> |
| 15 | + <tbody> |
| 16 | + <tr> |
| 17 | + <td><code class="csharp">ApplicationMemoryUsed</code><code class="python">APPLICATION_MEMORY_USED</code></td> |
| 18 | + <td><code class="csharp">long</code><code class="python">int</code></td> |
| 19 | + <td>Private memory allocated to the current process, including managed and unmanaged memory, in megabytes.</td> |
| 20 | + </tr> |
| 21 | + <tr> |
| 22 | + <td><code class="csharp">TotalPhysicalMemoryUsed</code><code class="python">TOTAL_PHYSICAL_MEMORY_USED</code></td> |
| 23 | + <td><code class="csharp">long</code><code class="python">int</code></td> |
| 24 | + <td>Managed-runtime RAM usage (sampled with <code class="csharp">GC.GetTotalMemory</code><code class="python">gc.get_total_memory</code>), in megabytes. LEAN's memory monitor samples this value.</td> |
| 25 | + </tr> |
| 26 | + <tr> |
| 27 | + <td><code class="csharp">CpuUsage</code><code class="python">CPU_USAGE</code></td> |
| 28 | + <td><code class="csharp">decimal</code><code class="python">float</code></td> |
| 29 | + <td>Total CPU usage as a percentage, sampled on a background thread.</td> |
| 30 | + </tr> |
| 31 | + <tr> |
| 32 | + <td><code class="csharp">GetServerStatistics()</code><code class="python">get_server_statistics()</code></td> |
| 33 | + <td><code class="csharp">Dictionary<string, string></code><code class="python">Dictionary[str, str]</code></td> |
| 34 | + <td>Snapshot dictionary with <code>CPU Usage</code>, <code>Used RAM</code>, <code>Total RAM</code>, <code>Hostname</code>, and <code>LEAN Version</code> entries.</td> |
| 35 | + </tr> |
| 36 | + </tbody> |
| 37 | +</table> |
| 38 | + |
| 39 | +<p>The following examples show how to read these metrics from an algorithm:</p> |
| 40 | + |
| 41 | +<div class="section-example-container"> |
| 42 | + <pre class="csharp">// Log the current memory usage of the algorithm process. |
| 43 | +Log($"Total physical memory used: {OS.TotalPhysicalMemoryUsed} MB"); |
| 44 | +Log($"Application memory used: {OS.ApplicationMemoryUsed} MB"); |
| 45 | + |
| 46 | +// Log the current CPU usage as a percentage. |
| 47 | +Log($"CPU usage: {OS.CpuUsage}%"); |
| 48 | + |
| 49 | +// Log a full snapshot of the server statistics. |
| 50 | +foreach (var kvp in OS.GetServerStatistics()) Log($"{kvp.Key}: {kvp.Value}");</pre> |
| 51 | + <pre class="python"># Log the current memory usage of the algorithm process. |
| 52 | +self.log(f"Total physical memory used: {OS.TOTAL_PHYSICAL_MEMORY_USED} MB") |
| 53 | +self.log(f"Application memory used: {OS.APPLICATION_MEMORY_USED} MB") |
| 54 | + |
| 55 | +# Log the current CPU usage as a percentage. |
| 56 | +self.log(f"CPU usage: {OS.CPU_USAGE}%") |
| 57 | + |
| 58 | +# Log a full snapshot of the server statistics. |
| 59 | +for kvp in OS.get_server_statistics(): |
| 60 | + self.log(f"{kvp.key}: {kvp.value}")</pre> |
| 61 | +</div> |
| 62 | + |
| 63 | +<p> |
| 64 | + LEAN monitors the process's RAM usage during backtests and live trading so it can stop the algorithm gracefully when it approaches the node's memory limit, instead of letting the runtime crash. |
| 65 | + To avoid killing an algorithm over a short-lived spike, LEAN does not act on the raw reading — it smooths the sampled value first and checks the smoothed value against the limit. |
| 66 | +</p> |
| 67 | + |
| 68 | +<p> |
| 69 | + LEAN samples <code class="csharp">OS.TotalPhysicalMemoryUsed</code><code class="python">OS.TOTAL_PHYSICAL_MEMORY_USED</code> once per minute and feeds each sample into an exponential moving average. |
| 70 | + The engine sets <code>emaPeriod = 60</code>, which gives you roughly a 1-hour rolling window. |
| 71 | +</p> |
| 72 | + |
| 73 | +<div class="section-example-container"> |
| 74 | + <pre class="csharp">// Update the smoothed memory reading each minute. |
| 75 | +sample = OS.TotalPhysicalMemoryUsed; |
| 76 | +memoryUsed = Convert.ToInt64((emaPeriod-1)/emaPeriod * memoryUsed + (1/emaPeriod)*sample);</pre> |
| 77 | + <pre class="python"># Update the smoothed memory reading each minute. |
| 78 | +sample = OS.TOTAL_PHYSICAL_MEMORY_USED |
| 79 | +memory_used = int((ema_period - 1) / ema_period * memory_used + (1 / ema_period) * sample)</pre> |
| 80 | +</div> |
| 81 | + |
| 82 | +<p> |
| 83 | + If the smoothed value exceeds the node's memory limit, LEAN terminates the algorithm with the runtime message <code>Execution Security Error: Memory Usage Maxed Out - {memoryCap}MB max, with last sample of {lastSample}MB.</code>, where <code>{memoryCap}</code> is the node's configured limit and <code>{lastSample}</code> is the most recent reading. |
| 84 | +</p> |
0 commit comments