Warnung, wenn verfügbarer RAM gegen Null geht

13

Dies ist eine Fortsetzung der Speicherbeschränkungslösungen für gierige Anwendungen, die das Betriebssystem zum Absturz bringen können. : ulimit und cgroups sind nicht benutzerfreundlich und funktionieren außerdem nicht mit Anwendungen, die separate Prozesse erzeugen, wie z. B. Chrome / Chromium für jede neue (Gruppe von) Registerkarten.

Die einfache und effektive Lösung, die von Windows 7 verwendet wird, besteht darin, den Benutzer zu warnen, dass dem Betriebssystem der Arbeitsspeicher ausgeht. Dieses einfache Warn-Popup hat mich daran gehindert, dass das System unter Windows aufgrund von wenig Speicherplatz einfriert, während ich auf Ubuntu-Distributionen, die ich live getestet habe (wo die auf dem RAM montierte Festplatte allein 2 GB verschlingt), immer wieder darauf stoße.

Gibt es also eine Möglichkeit, den Benutzer automatisch zu warnen, dass der verfügbare RAM gegen Null geht, ohne dass der Benutzer ein Speicherüberwachungs-Gadget im Auge behalten muss? Sicherlich könnte Conky dafür konfiguriert sein?

Dan Dascalescu
quelle
2
Vier Jahre später scheint eine regelmäßige Überprüfung free -mder richtige Weg zu sein.
Dan Dascalescu

Antworten:

8

Überprüfen Sie diese Skripte: Benötigen Sie eine Anwendungs- / Skriptwarnung, wenn der Systemspeicher knapp wird

#!/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();
?>
StandardSpezifikation
quelle
1
Das Skript funktioniert mit kleinen Anpassungen (die ich gerade verwendet habe available=$(free -m | grep Mem | awk '{print $7}')). Informationen
morsch
Wenn die Sprache nicht Englisch ist, gibt der freie Wille lokalisierten Text aus und die Analyse schlägt fehl. LANG=en_US.UTF-8Fügen Sie dann zu Beginn des Bash-Skripts hinzu.
Freddi Schiller
2

Ein weiteres Skript, das ich zu diesem Zweck geschrieben habe:

#!/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
quelle
Warum oder warum wird notify-sendder Timeout-Parameter ignoriert : - / Und warum gibt es keine Dokumentation zu den Kategorien und Aktiensymbolen? Außerdem werden Zeilenumbrüche ignoriert und die Nachricht wird abgeschnitten . -u criticallöst das.
Dan Dascalescu
Technisch notify-sendignoriert das Timeout nicht. Es ist der Prozess, der die Benachrichtigung als Eingabe verwendet und über dem Desktop anzeigt, der entscheidet, das Zeitlimit zu ignorieren. Siehe auch: unix.stackexchange.com/q/251243/20336
Mikko Rantalainen
1

Aktualisierte Version des Skripts, die kostenlos mit procps-ng 3.3.10 funktioniert

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

Das obige Skript wurde aktualisiert, um auch Details zu den drei wichtigsten speicherhungrigen Prozessen hinzuzufügen. Siehe unter https://github.com/romanmelko/ubuntu-low-mem-popup

Hier ist das Skript selbst:

#!/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
quelle
Vielen Dank für Ihren Beitrag. Die bessere Vorgehensweise besteht darin, den Inhalt des Links, auf den Sie verweisen, zusammenzufassen (in diesem Fall zu kopieren). Auf diese Weise bleibt Ihre Antwort auch dann gültig, wenn der Link verschwindet.
Marc Vanhoomissen
1

Variante mit verfügbarem RAM , Prozentsätzen und Anzeige von Desktop-Benachrichtigungen beim Aufruf von cron (dh das Schleifenskript muss nach dem Neustart nicht gestartet werden):

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