Advertencia cuando la RAM disponible se acerca a cero

13

Este es un seguimiento de las soluciones de limitación de memoria para aplicaciones codiciosas que pueden bloquear el sistema operativo? : ulimit y cgroups no son fáciles de usar y, además, no funcionarían con aplicaciones que generen procesos separados, como Chrome / Chromium para cada nueva pestaña (grupo de).

La solución simple y efectiva, utilizada por Windows 7 en realidad, es advertir al usuario que el sistema operativo se está quedando sin memoria. Esta simple ventana emergente de advertencia me ha impedido que se congele el sistema con poca memoria en Windows, mientras seguía encontrándome con ellos en las distribuciones de Ubuntu que estaba probando en vivo (donde el disco montado en RAM consumiría solo 2 GB).

Entonces, ¿hay alguna forma de advertir automáticamente al usuario que la RAM disponible está cerca de cero, sin que el usuario tenga que vigilar algún dispositivo de monitoreo de memoria? ¿Seguramente Conky podría configurarse para hacer eso?

Dan Dascalescu
fuente
2
Cuatro años después , parece que verificar periódicamente free -mes el camino a seguir.
Dan Dascalescu

Respuestas:

8

Verifique estos scripts: necesita alertas de aplicación / script cuando la memoria del sistema se está agotando

#!/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();
?>
Especificacion estandar
fuente
1
El guión funciona con pequeñas adaptaciones (que acabo de usar available=$(free -m | grep Mem | awk '{print $7}')). Para hacer que el envío de notificaciones funcione con cron, consulte anmolsinghjaggi.wordpress.com/2016/05/11/…
morsch
Si el idioma no es inglés, el libre albedrío generará texto localizado y el análisis fallará. Luego agregue LANG=en_US.UTF-8al comienzo del script bash.
Freddi Schiller
2

Otro script que escribí para este propósito:

#!/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
Mikko Rantalainen
fuente
¿Por qué o por qué notify-sendignora el parámetro de tiempo de espera : - / Y por qué no hay documentación sobre cuáles son las categorías y los iconos de valores? Además, las líneas nuevas se ignoran y el mensaje se trunca . -u criticalresuelve eso.
Dan Dascalescu
Técnicamente notify-sendno ignora el tiempo de espera. Es el proceso que toma la notificación como entrada y la muestra sobre el escritorio que decide ignorar el tiempo de espera. Ver también: unix.stackexchange.com/q/251243/20336
Mikko Rantalainen
1

Versión actualizada del script que funciona con libre de procps-ng 3.3.10

#!/bin/bash

#Minimum available memory limit, MB
THRESHOLD=400

#Check time interval, sec
INTERVAL=30

while :
do
    free_out=$(free -w -m)
    available=$(awk '/^Mem:/{print $8}' <<<$free_out)

    if (( $available < $THRESHOLD ))
        then
        notify-send -u critical "Memory is running out!" "Available memory is $available MiB"
        echo "Warning - available memory is $available MiB"    
    fi

    cat <<<$free_out
    sleep $INTERVAL
done
Jirka Hladky
fuente
1

Se actualizó el script anterior para agregar también detalles sobre los 3 principales procesos que requieren mucha memoria. Ver en https://github.com/romanmelko/ubuntu-low-mem-popup

Aquí está el script en sí:

#!/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
Roman Melko
fuente
Gracias por tu aporte. La mejor práctica aquí es resumir (en este caso copiar) el contenido del enlace al que hace referencia. De esta manera, su respuesta sigue siendo válida incluso si el enlace desaparece.
Marc Vanhoomissen
1

Variante que usa RAM disponible , porcentajes y muestra notificaciones de escritorio cuando es llamado por cron (es decir, el script de bucle no tiene que iniciarse después del reinicio):

#!/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
Lambfrier
fuente