Tom Wojcik personal blog

Monitoring Memory Usage on Ubuntu with Bash and systemctl

☕️ 3 min read

Sometimes, when running an extensive test suite with a debugger, my laptop tends to freeze. I managed to figure out that it’s due to running out of memory. The weirdest thing is that it happens only when using PyCharm with debugger. Although I need my local setup to be working fine, what I need more is a dev env that doesn’t freeze, which forces me to hard reboot. I figured, that it’s a good idea to alert myself, whenever memory consumption threshold is exceeded.

This guide will walk you through a simple yet effective method to monitor memory usage on Ubuntu using Bash scripting and systemctl.

Step 1: Crafting the Memory Monitoring Script

To begin, let’s create a Bash script that continuously monitors memory usage and alerts us when it exceeds predefined thresholds. Open your terminal and create the script:

sudo vi /usr/local/bin/memory_monitor_script.sh

/usr/local/bin is for programs that a normal user may run. Read more on https://unix.stackexchange.com/questions/4186/what-is-usr-local-bin.

Now, let’s add the following content to the script:

#!/bin/bash

while true; do
    # Get memory usage percentage
    memory_usage=$(free | awk '/Mem/{printf("%.2f"), $3/$2 * 100}')

    # Check if memory usage exceeds 80%
    if (( $(echo "$memory_usage > 80" | bc -l) )); then
        # Display a warning message
        notify-send "Memory Usage Warning" "Memory usage is above 80%: $memory_usage%"
    fi

    # Check every 5 seconds (adjust interval as needed)
    sleep 5
done

Once done, save the changes and close the editor.

Step 2: Making the Script Executable

Let’s ensure our script has the necessary permissions to do its job:

sudo chmod +x /usr/local/bin/memory_monitor_script.sh

Step 3: Setting Up systemctl

Next, we’ll create a systemd service unit file to manage our memory monitoring script. Open a new file in the /etc/systemd/system directory:

sudo vi /etc/systemd/system/memory_monitor.service

Add the following content to the file:

[Unit]
Description=Memory Monitoring Script
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/memory_monitor_script.sh

[Install]
WantedBy=multi-user.target

Save the changes and close the editor.

Step 4: Enabling and Starting the Service

Now, let’s enable and start the service:

sudo systemctl enable memory_monitor
sudo systemctl start memory_monitor

Step 5: Checking the Status

To check the status of the memory monitoring service, you can use the following command:

sudo systemctl status memory_monitor

You’re looking for

Active: active (running)

Step 6: Enhancing Memory Management

In addition to alerting you when memory usage exceeds 80%, you can further optimize memory management by stopping resource-intensive processes. For example, if memory usage exceeds 90%, you can automatically stop Docker containers and kill PyCharm. Here’s my approach

#!/bin/bash

while true; do
    # Get memory usage percentage
    memory_usage=$(free | awk '/Mem/{printf("%.2f"), $3/$2 * 100}')

    # Check if memory usage exceeds 80%
    if (( $(echo "$memory_usage > 80" | bc -l) )); then
        # Display a warning message
        notify-send "Memory Usage Warning" "Memory usage is above 80%: $memory_usage%"
    fi

    # Check if memory usage exceeds 90%
    if (( $(echo "$memory_usage > 90" | bc -l) )); then
        # kill pycharm
        kill $(pgrep -f "pycharm")
        # wait a moment to make sure the process is not using docker anymore
        sleep 2
        # stop all docker containers
        docker stop $(docker ps -a -q)
    fi

    # Check every 5 seconds (adjust interval as needed)
    sleep 5
done

The memory monitoring script will now run automatically at system startup (for all users) and alert you if needed.