Avertissement lorsque la RAM disponible approche de zéro

13

Il s'agit d'un suivi des solutions de limitation de mémoire pour les applications gourmandes qui peuvent planter le système d'exploitation? : ulimit et cgroups ne sont pas conviviaux et, en outre, ne fonctionneraient pas avec des applications qui engendrent des processus distincts, tels que Chrome / Chromium pour chaque nouvel (groupe d'onglets).

La solution simple et efficace, utilisée par Windows 7 en fait, consiste à avertir l'utilisateur que le système d'exploitation manque de mémoire. Ce simple pop-up d'avertissement m'a empêché d'avoir un gel du système provoqué par une faible mémoire dans Windows, alors que je continuais à les rencontrer sur des distributions Ubuntu que je testais en direct (où le disque monté sur la RAM consommerait 2 Go seul).

Alors, existe-t-il un moyen d'avertir automatiquement l'utilisateur que la RAM disponible est proche de zéro, sans que l'utilisateur n'ait à surveiller un gadget de surveillance de la mémoire? Certes, Conky pourrait être configuré pour le faire?

Dan Dascalescu
la source
2
Quatre ans plus tard , il semble que la vérification périodique free -mest la voie à suivre.
Dan Dascalescu

Réponses:

8

Vérifiez ces scripts: besoin d'une alerte d'application / de script lorsque la mémoire système est épuisée

#!/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();
?>
Spécification standard
la source
1
Le script fonctionne avec de petites adaptations (je viens de l'utiliser available=$(free -m | grep Mem | awk '{print $7}')). Pour faire fonctionner notifier-envoyer avec cron, reportez-vous à anmolsinghjaggi.wordpress.com/2016/05/11/…
morsch
Si la langue n'est pas l'anglais, free affichera du texte localisé et l'analyse échouera. Ajoutez ensuite LANG=en_US.UTF-8au début du script bash.
Freddi Schiller
2

Un autre script que j'ai écrit à cet effet:

#!/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
la source
Pourquoi o pourquoi notify-sendignore le paramètre timeout : - / Et pourquoi n'y a-t-il pas de documentation sur les catégories et les icônes boursières? En outre, les sauts de ligne sont ignorés et le message est tronqué . -u criticalrésout cela.
Dan Dascalescu
Techniquement, notify-sendn'ignore pas le délai d'expiration. C'est le processus qui prend la notification en entrée et l'affiche au-dessus du bureau qui décide d'ignorer le délai d'expiration. Voir aussi: unix.stackexchange.com/q/251243/20336
Mikko Rantalainen
1

Version mise à jour du script qui fonctionne avec free from 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
la source
1

Mise à jour du script ci-dessus pour ajouter également des détails sur les 3 principaux processus gourmands en mémoire. Voir sur https://github.com/romanmelko/ubuntu-low-mem-popup

Voici le script lui-même:

#!/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
la source
Merci pour votre contribution. La meilleure pratique ici est de résumer (dans ce cas une copie) le contenu du lien auquel vous faites référence. De cette façon, votre réponse reste valable même si le lien disparaît.
Marc Vanhoomissen
1

Variante utilisant la RAM disponible , des pourcentages et affiche les notifications du bureau lorsqu'elle est appelée par cron (c'est-à-dire que le script de boucle ne doit pas être démarré après le redémarrage):

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