Monitor .NET Process Memory in Linux/WSL
Resource-heavy .NET work, such as OCR, PDF generation, or image processing, can be hard to size up in constrained environments like WSL (Windows Subsystem for Linux) or Linux containers. You can log a process's memory consumption in real time directly from a console app, or watch it externally with standard Linux tools.
Prerequisites
- .NET SDK installed, version
5.0or later. - A Linux environment, either native or via WSL.
- A basic .NET console app.
Solution
1. Log memory usage to the console
Read the process's private memory size and print it in megabytes:
using System;
using System.Diagnostics;
class Program
{
static void Main(string[] args)
{
// Trigger your memory-consuming logic here (e.g., OCR, PDF generation, etc.)
// Log memory usage
Process currentProcess = Process.GetCurrentProcess();
long memorySize = currentProcess.PrivateMemorySize64; // In bytes
Console.WriteLine($"Memory Usage: {memorySize / (1024 * 1024)} MB");
}
}
using System;
using System.Diagnostics;
class Program
{
static void Main(string[] args)
{
// Trigger your memory-consuming logic here (e.g., OCR, PDF generation, etc.)
// Log memory usage
Process currentProcess = Process.GetCurrentProcess();
long memorySize = currentProcess.PrivateMemorySize64; // In bytes
Console.WriteLine($"Memory Usage: {memorySize / (1024 * 1024)} MB");
}
}
Imports System
Imports System.Diagnostics
Class Program
Shared Sub Main(ByVal args As String())
' Trigger your memory-consuming logic here (e.g., OCR, PDF generation, etc.)
' Log memory usage
Dim currentProcess As Process = Process.GetCurrentProcess()
Dim memorySize As Long = currentProcess.PrivateMemorySize64 ' In bytes
Console.WriteLine($"Memory Usage: {memorySize / (1024 * 1024)} MB")
End Sub
End Class
PrivateMemorySize64 returns the amount of memory, in bytes, that the process has allocated exclusively and does not share with other processes. It's a solid indicator of how heavy your application is running.
2. Track memory continuously
For a long-running process, wrap the read in a loop to sample usage over time:
while (true)
{
var memory = Process.GetCurrentProcess().PrivateMemorySize64;
Console.WriteLine($"Memory Usage: {memory / (1024 * 1024)} MB");
Thread.Sleep(5000); // Log every 5 seconds
}
while (true)
{
var memory = Process.GetCurrentProcess().PrivateMemorySize64;
Console.WriteLine($"Memory Usage: {memory / (1024 * 1024)} MB");
Thread.Sleep(5000); // Log every 5 seconds
}
Imports System.Diagnostics
Imports System.Threading
While True
Dim memory = Process.GetCurrentProcess().PrivateMemorySize64
Console.WriteLine($"Memory Usage: {memory / (1024 * 1024)} MB")
Thread.Sleep(5000) ' Log every 5 seconds
End While
The Thread.Sleep(5000) call paces the logging to one reading every five seconds. Pipe the output to a file or another process, or use it to fire alerts when usage crosses a threshold.
Console Output
Memory Usage: 214 MB
Option: Monitor externally with Linux tools
To watch a process from outside the app, use one of the standard utilities. <PID> is the Process ID, the unique number the operating system assigns to each running process.
top or htop: watch a single process live.
top -p <PID>
top -p <PID>
ps: print a one-shot snapshot of memory fields.
ps -o pid,vsz,rss,comm -p <PID>
ps -o pid,vsz,rss,comm -p <PID>
Here VSZ is the virtual memory size in KB and RSS is the resident set size, the physical memory in use.
smem: install it for a more detailed per-process breakdown.
sudo apt install smem
smem -p <PID>
sudo apt install smem
smem -p <PID>
Best Practices
- Run memory tracking in test environments before deploying to production.
- For long-running services or APIs, integrate a metrics stack such as Prometheus or Grafana.
- Reserve
GC.Collect()for debugging only.

