Warning when available RAM approaches zero

12,052

Solution 1

Check these scripts: Need application/script alerting when system memory is running out

#!/bin/bash

#Minimum available memory limit, MB
THRESHOLD=400

#Check time interval, sec
INTERVAL=30

while :
do

    free=$(free -m|awk '/^Mem:/{print $4}')
    buffers=$(free -m|awk '/^Mem:/{print $6}')
    cached=$(free -m|awk '/^Mem:/{print $7}')
    available=$(free -m | awk '/^-\/+/{print $4}')

    message="Free $free""MB"", buffers $buffers""MB"", cached $cached""MB"", available $available""MB"""

    if [ $available -lt $THRESHOLD ]
        then
        notify-send "Memory is running out!" "$message"
    fi

    echo $message

    sleep $INTERVAL

done

PHP:

#!/usr/bin/php
<?php
$alert_percent=($argc>1)?(int)$argv[1]:90;
//$interval=($argc>2):(int)$argv[2]:25;



//while(true)
//{
 exec("free",$free);

$free=implode(' ',$free);
preg_match_all("/(?<=\s)\d+/",$free,$match);

list($total_mem,$used_mem,$free_mem,$shared_mem,$buffered_mem,$cached_mem)=$match[0];

$used_mem-=($buffered_mem+$cached_mem);

$percent_used=(int)(($used_mem*100)/$total_mem);

if($percent_used>$alert_percent)
exec("notify-send 'Low Memory: $percent_used% used'");

//sleep($interval);
//}
exit();
?>

Solution 2

Another script that I wrote for this purpose:

#!/bin/bash
# Copyright 2019, Mikko Rantalainen
# License: MIT X License

# Minimum available memory until warning, default to 10% of total RAM (MiB)
THRESHOLD=$(grep "MemTotal:" /proc/meminfo | awk '{ printf "%d", 0.1*$2/1024}')
INTERVAL=60s

echo "Emitting a warning if less than $THRESHOLD MiB of RAM is available..."

while true; do
    meminfo=$(cat /proc/meminfo)
    free=$(echo "$meminfo" | grep "MemFree:" | awk '{ printf "%d", $2/1024}')
    available=$(echo "$meminfo" | grep "MemAvailable:" | awk '{ printf "%d", $2/1024}')
    inactive=$(echo "$meminfo" | grep "Inactive:" | awk '{ printf "%d", $2/1024}')
    reclaimable=$(echo "$meminfo" | grep "SReclaimable:" | awk '{ printf "%d", $2/1024}')
    usable=$(echo "$free + $inactive / 2 + $reclaimable / 2" | bc)
    if test -z "$available"; then
        message="Current kernel does not support MemAvailable in /proc/meminfo, aborting"
        notify-send "Error while monitoring low memory" "$message"
        echo "$message" 1>&2
        exit 1
    fi

    message="Available: $available MiB
Free: $free MiB
Maybe usable: $usable MiB"

    if [ "$available" -lt "$THRESHOLD" ]
        then
        notify-send -u critical "Low memory warning" "$message"
        echo "Low memory warning:"
    echo "$message"
    fi

    #echo "DEBUG: $message"
    sleep $INTERVAL
done

Solution 3

This cron job that runs every 1 min

* * * * * if [ $(free -wm | awk ' /^Mem:/ { print $8 } ') -le 400 ]; then XDG_RUNTIME_DIR=/run/user/$(id -u) notify-send 'Short on memory!'; fi

To add it you run crontab -e and paste it at the bottom. You have to have cron installed

Solution 4

Updated above script to also add details on top 3 memory-hungry processes. See at https://github.com/romanmelko/ubuntu-low-mem-popup

Here is the script itself:

#!/usr/bin/env bash

set -o errexit
set -o pipefail
set -o nounset

# If the language is not English, free will output localized text and parsing fails
LANG=en_US.UTF-8

THRESHOLD=500
INTERVAL=300
POPUP_DELAY=999999

# sleep some time so the shell starts properly
sleep 60

while :
do
    available=$(free -mw | awk '/^Mem:/{print $8}')
    if [ $available -lt $THRESHOLD ]; then
        title="Low memory! $available MB available"
        message=$(top -bo %MEM -n 1 | grep -A 3 PID | awk '{print $(NF - 6) " \t" $(NF)}')
        # KDE Plasma notifier
        kdialog --title "$title" --passivepopup "$message" $POPUP_DELAY
        # use the following command if you are not using KDE Plasma, comment the line above and uncomment the line below
        # please note that timeout for notify-send is represented in milliseconds
        # notify-send -u critical "$title" "$message" -t $POPUP_DELAY
    fi
    sleep $INTERVAL
done

Solution 5

Variant using RAM available, percentages and displays desktop notifications when called by cron (i.e. loop script doesn't have to be started after reboot):

#!/usr/bin/env bash

# dbus env var required when called via cron:
eval "export $(egrep -z DBUS_SESSION_BUS_ADDRESS /proc/$(pgrep -u $LOGNAME gnome-session)/environ | tr '\0' '\n')";

AVAIL_THRESHOLD=5

free_output=$(free)
mem_total=$(awk '/^Mem:/{print $2}' <<< $free_output)
mem_avail=$(awk '/^Mem:/{print $7}' <<< $free_output)
mem_avail_m=$(bc <<< "scale=1; $mem_avail/1024")
percent_avail=$(bc <<< "scale=1; $mem_avail*100 /$mem_total")
should_warn=$(bc <<< "$percent_avail < $AVAIL_THRESHOLD")

if (( $should_warn )); then
    notify-send "Memory warning - only $percent_avail% ($mem_avail_m MB) available"
else
    echo "Memory OK - $percent_avail% ($mem_avail_m MB) available"
fi
Share:
12,052

Related videos on Youtube

Dan Dascalescu
Author by

Dan Dascalescu

Bio Co-founded the visa-free startup ship, Blueseed, the Quantified Self Forum (a community for self-trackers), and two web startups using meteor. Former Developer Advocate at Google - Progressive Web Apps (PWA), Accelerated Mobile Pages (AMP), Chrome OS, and AR (Lens). Former localization engineer at Yahoo!. I currently discourage localization in general, for reasons I haven't seen successfully challenged since 2009, with the exception of translating basic computer programming materials as a way to onboard new developers. More about me on on Wikipedia or on my website. My CV is on StackOverflow Careers. Interests Entrepreneurship and disruptive technologies, biotech, 3D printing, brain-computer interfaces, prediction markets. Applying ~20 years of experience in software development and ~5 in the startup world in CTO roles at emergent tech companies. Thanks If you feel grateful, here's my Amazon wishlist.

Updated on September 18, 2022

Comments

  • Dan Dascalescu
    Dan Dascalescu over 1 year

    This is a follow-up to Memory limiting solutions for greedy applications that can crash OS?: ulimit and cgroups are not user friendly, and besides, wouldn't work with applications that spawn separate processes, such as Chrome/Chromium for each new (group of) tabs.

    The simple and effective solution, used by Windows 7 actually, is to warn the user that the OS is running low on memory. This simple warning pop-up has prevented me from having any low-memory-caused system freeze in Windows, while I kept running into them on Ubuntu distros that I was testing live (where the RAM-mounted disk would eat up 2GB alone).

    So, is there some way to automatically warn the user that the available RAM is nearing zero, without the user having to keep an eye on some memory monitoring gadget? Surely Conky could be configured to do that?

  • morsch
    morsch almost 8 years
    The script works with small adaptations (I just used available=$(free -m | grep Mem | awk '{print $7}')). To make notify-send work with cron, refer to anmolsinghjaggi.wordpress.com/2016/05/11/…
  • Freddi Schiller
    Freddi Schiller almost 7 years
    If the language is not English, free will output localized text and parsing fails. Then add LANG=en_US.UTF-8 at the beginnning of the bash script.
  • Dan Dascalescu
    Dan Dascalescu over 5 years
    Why o why does notify-send ignore the timeout parameter :-/ And why is there no documentation about what the categories and stock icons are? Also, newlines are ignored and the message gets truncated. -u critical solves that.
  • Mikko Rantalainen
    Mikko Rantalainen over 5 years
    Technically notify-send does not ignore the timeout. It's the process that takes the notication as input and displays it above the desktop that decides to ignore the timeout. See also: unix.stackexchange.com/q/251243/20336
  • Marc Vanhoomissen
    Marc Vanhoomissen about 5 years
    Thank you for for contribution. The better practice here is to summarize (in this case copy) the content of the link you refer to. This way, your answer remains valid even if the link disappears.
  • BT643
    BT643 over 2 years
    Thanks for this, I for anyone else's benefit, I changed it slightly to make it stay on the screen until you click to get rid of so I don't accidentally miss any. * * * * * if [ $(free -wm | awk ' /^Mem:/ { print $8 } ') -le 400 ]; then XDG_RUNTIME_DIR=/run/user/$(id -u) notify-send -u critical -t 0 'Short on memory!'; fi