Avviso quando la RAM disponibile si avvicina a zero


13

Questo è un seguito alle soluzioni di limitazione della memoria per applicazioni avide che possono arrestare il sistema operativo? : ulimit e cgroups non sono facili da usare e inoltre non funzionerebbero con applicazioni che generano processi separati, come Chrome / Chromium per ogni nuovo (gruppo di) schede.

La soluzione semplice ed efficace, attualmente utilizzata da Windows 7, è quella di avvisare l'utente che il sistema operativo sta esaurendo la memoria. Questo semplice avviso pop-up mi ha impedito di avere qualsiasi blocco del sistema causato da memoria insufficiente in Windows, mentre continuavo a imbattermi in distribuzioni Ubuntu che stavo testando dal vivo (dove il disco montato su RAM avrebbe consumato solo 2 GB).

Quindi, c'è un modo per avvisare automaticamente l'utente che la RAM disponibile si avvicina allo zero, senza che l'utente debba tenere d'occhio un gadget di monitoraggio della memoria? Sicuramente Conky potrebbe essere configurato per farlo?


2
Quattro anni dopo , sembra che il controllo periodico free -msia la strada da percorrere.
Dan Dascalescu,

Risposte:


8

Controllare questi script: è necessario un avviso applicazione / script quando la memoria di sistema si sta esaurendo

#!/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();
?>

1
La sceneggiatura funziona con piccoli adattamenti (ho appena usato available=$(free -m | grep Mem | awk '{print $7}')). Per far funzionare le notifiche con cron, fai
morsch

Se la lingua non è l'inglese, il libero arbitrio genera testo localizzato e l'analisi non riesce. Quindi aggiungi LANG=en_US.UTF-8all'inizio dello script bash.
Freddi Schiller,

2

Un'altra sceneggiatura che ho scritto per questo scopo:

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

Perché o perché notify-sendignora il parametro di timeout : - / E perché non c'è documentazione su quali siano le categorie e le icone di borsa? Inoltre, le nuove righe vengono ignorate e il messaggio viene troncato . -u criticallo risolve.
Dan Dascalescu,

Tecnicamente notify-sendnon ignora il timeout. È il processo che prende la notifica come input e la visualizza sopra il desktop che decide di ignorare il timeout. Vedi anche: unix.stackexchange.com/q/251243/20336
Mikko Rantalainen

1

Versione aggiornata dello script che funziona gratuitamente da 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

1

Aggiornato lo script sopra per aggiungere dettagli sui primi 3 processi affamati di memoria. Vedi https://github.com/romanmelko/ubuntu-low-mem-popup

Ecco lo script stesso:

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

Grazie per il contributo. La migliore pratica qui è di riassumere (in questo caso copiare) il contenuto del collegamento a cui si fa riferimento. In questo modo, la tua risposta rimane valida anche se il collegamento scompare.
Marc Vanhoomissen,

1

Variante che utilizza la RAM disponibile , percentuali e visualizza le notifiche desktop quando viene chiamata da cron (ovvero non è necessario avviare lo script di loop dopo il riavvio):

#!/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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.