[gelöst] 🫗 Speicherleck in FHEMWEB? Virtual Memory Size VSZ wächst stetig

Begonnen von Torxgewinde, 24 Oktober 2023, 21:55:19

Vorheriges Thema - Nächstes Thema

Torxgewinde

Hallo!
Ich glaube wir haben ein Speicherleck in FHEMWEB.

Der folgende SVG-Plot zeigt wie der Speicherverbrauch "VSZ" bei einem Request pro Sekunde ansteigt:
Du darfst diesen Dateianhang nicht ansehen.

Um es reproduzierbar zu gestalten, habe ich ich die folgenden Schritte dokumentiert:

1. FHEM in einer Chroot-Umgebung installieren (siehe auch: https://forum.fhem.de/index.php?topic=134680.0):
#!/bin/sh

THIS_BASE="/mnt/USB"
THIS_CHROOT="$THIS_BASE/speicherleckTest"
THIS_CACHE="$THIS_BASE/cache"

#ARCH="arm64"
#ARCH="armhf"
#ARCH="armel"
ARCH="amd64"

#check if curl is installed
echo "checking if curl is installed:"
which curl || exit 1

echo "changing to directory: $THIS_BASE"
mkdir -p "$THIS_CHROOT" || exit 1
mkdir -p "$THIS_CACHE" || exit 1
cd "$THIS_BASE" || exit 1

# Extract the most recent version from the index page using curl and grep, the GET parameters sort it for us
LATEST_PACKAGE=$(curl -s "http://ftp.debian.org/debian/pool/main/c/cdebootstrap/?C=M;O=D" | grep "$ARCH"| grep -o "cdebootstrap-static_[^\"]*deb" | head -n1)
if [ -z "$LATEST_PACKAGE" ]; then
  echo "Failed to extract the latest package name."
  exit 1
fi
DOWNLOAD_URL="http://ftp.debian.org/debian/pool/main/c/cdebootstrap/$LATEST_PACKAGE"

echo "Downloading cdebootstrap-static: $DOWNLOAD_URL"
while true; do
    wget -O "$THIS_CACHE/cdebootstrap-static.deb" "$DOWNLOAD_URL" && break
    sleep 5
done

echo "unpacking cdebootstrap-static:"
cd "$THIS_CACHE"
ar x cdebootstrap-static.deb || exit 1
tar xvf data.tar.xz || exit 1

echo "Executing cdebootstrap-static:"
./usr/bin/cdebootstrap-static --arch $ARCH --configdir=./usr/share/cdebootstrap-static --helperdir=./usr/share/cdebootstrap-static/ stable "$THIS_CHROOT" || exit 1

#fhem package needs mount points, or it fails:
mount -t proc proc "$THIS_CHROOT/proc/" || exit 1
mount -t sysfs sys "$THIS_CHROOT/sys/" || exit 1
mount -o bind /dev "$THIS_CHROOT/dev/" || exit 1
mount -o bind /dev/pts "$THIS_CHROOT/dev/pts" || exit 1

echo "Installing additional packages in chroot:"
chroot "$THIS_CHROOT" apt update || exit 1
chroot "$THIS_CHROOT" apt -y install vim wget curl htop bash-completion gpg locales mpc ffmpeg \
                                     libxml-libxml-perl sqlite3 libdbi-perl \
                                     libdbd-sqlite3-perl libdigest-sha-perl \
                                     libmime-base64-urlsafe-perl libmime-base64-perl \
                                     libcrypt-cbc-perl libio-socket-ssl-perl libsoap-lite-perl \
                                     libhttp-request-ascgi-perl liblwp-protocol-https-perl \
                                     libhtml-parser-perl libwww-perl libdigest-sha-perl \
                                     libtest-lwp-useragent-perl libmemory-usage-perl || exit 1

echo "Setting timezone:"
chroot "$THIS_CHROOT" bash -c "ln -fs /usr/share/zoneinfo/Europe/Berlin /etc/localtime && \
                               dpkg-reconfigure --frontend noninteractive tzdata" || exit 1
                               
echo "configuring German as locale:"
chroot "$THIS_CHROOT" bash -c "echo \
'LANG=de_DE.UTF-8
LC_MESSAGES=de_DE.UTF-8
LC_COLLATE=de_DE.UTF-8
LC_TIME=de_DE.UTF-8' > /etc/default/locale" || exit 1
chroot "$THIS_CHROOT" bash -c "echo 'en_US.UTF-8 UTF-8' | tee -a /etc/locale.gen" || exit 1
chroot "$THIS_CHROOT" bash -c "echo 'de_DE.UTF-8 UTF-8' | tee -a /etc/locale.gen" || exit 1
chroot "$THIS_CHROOT" bash -c "locale-gen" || exit 1
chroot "$THIS_CHROOT" bash -c "update-locale LANG=de_DE.UTF-8" || exit 1

echo "Installing FHEM in chroot:"
chroot "$THIS_CHROOT" /bin/bash -c 'wget -O- https://debian.fhem.de/archive.key | gpg --dearmor > /usr/share/keyrings/debianfhemde-archive-keyring.gpg' || exit 1
chroot "$THIS_CHROOT" /bin/bash -c 'echo "deb [signed-by=/usr/share/keyrings/debianfhemde-archive-keyring.gpg] https://debian.fhem.de/nightly/ /" >> /etc/apt/sources.list' || exit 1
chroot "$THIS_CHROOT" apt update || exit 1
chroot "$THIS_CHROOT" apt -y install fhem || exit 1

##Set ownership to user "fhem" and group "dialout"
chroot "$THIS_CHROOT" /bin/bash -c "chown -R fhem:dialout /opt/fhem" || exit 1

#cleaning up
rm -rf "$THIS_CACHE" || exit 1
umount "$THIS_CHROOT/dev/pts" || exit 1
umount "$THIS_CHROOT/proc/" || exit 1
umount "$THIS_CHROOT/sys/" || exit 1
umount -l "$THIS_CHROOT/dev/" || exit 1

echo "$0: all done!"
exit 0

2. minimale Testconfig "fhem.cfg" für FHEM in der Chroot (Den Speicherverbrauch messe ich mit https://forum.fhem.de/index.php?topic=135407.0):
attr global userattr cmdIcon devStateIcon:textField-long devStateStyle icon sortby webCmd webCmdLabel:textField-long widgetOverride
attr global autoload_undefined_devices 1
attr global logfile ./log/fhem-%Y-%m.log
attr global modpath .
attr global nofork 1
attr global statefile ./log/fhem.save
attr global verbose 3

define WEB FHEMWEB 8083 global
setuuid WEB 6537ff55-f33f-467c-ada1-ef606ba23f7ca1ac
attr WEB closeConn 1
attr WEB longpollSVG 1
attr WEB plotEmbed 2
attr WEB plotfork 1

# Fake FileLog entry, to access the fhem log from FHEMWEB
define Logfile FileLog ./log/fhem-%Y-%m.log Logfile
setuuid Logfile 6537ff55-f33f-467c-e1c1-cb7f9c44e9f3c7d8

define autocreate autocreate
setuuid autocreate 6537ff55-f33f-467c-9935-c358913fddcf2fe0
attr autocreate filelog ./log/%NAME-%Y.log

define eventTypes eventTypes ./log/eventTypes.txt
setuuid eventTypes 6537ff55-f33f-467c-73ac-359ec2da3cb36775

# Disable this to avoid looking for new USB devices on startup
#define initialUsbCheck notify global:INITIALIZED usb create

define memUsageDevice dummy
setuuid memUsageDevice 65317e28-f33f-ee6b-fada-b64a23ba0c59f3c5
attr memUsageDevice readingList wert
attr memUsageDevice setList wert
attr memUsageDevice stateFormat timestamp_diff, VSZ, VSZ_diff
attr memUsageDevice userReadings check:wert:\scheck$ {\
    use Memory::Usage;;\
    my $result = "initialized...";;\
\
    # Read result and keep it\
    if (defined($hash->{helper}{mu})) {\
        $hash->{helper}{mu}->record();;\
        my $state_ref = $hash->{helper}{mu}->state;;\
\
        if (scalar(@$state_ref) == 2) {\
            my ($timestamp1, $message1, $vsz1, $rss1, $shared1, $text1, $data_stack1) = @{$state_ref->[0]};;\
            my ($timestamp2, $message2, $vsz2, $rss2, $shared2, $text2, $data_stack2) = @{$state_ref->[1]};;\
\
            my $timestamp_d = $timestamp2 - $timestamp1;; #time in seconds between records\
            my $vsz_d = $vsz2 - $vsz1;; #virtual memory size\
            my $rss_d = $rss2 - $rss1;; #resident set size\
            my $shared_d = $shared2 - $shared1;; #shared memory size\
            my $text_d = $text2 - $text1;; #text (aka code or exe) size\
            my $data_stack_d = $data_stack2 - $data_stack1;; #data and stack size\
\
            $result  = sprintf("Total: Timestamp: %12d, VSZ: %8d, RSS: %8d, Shared: %8d, Text: %6d, Data_Stack: %8d\n",\
                               $timestamp2, $vsz2, $rss2, $shared2, $text2, $data_stack2);;\
            $result .= sprintf("Diffs: Timestamp: %12d, VSZ: %8d, RSS: %8d, Shared: %8d, Text: %6d, Data_Stack: %8d",\
                               $timestamp_d, $vsz_d, $rss_d, $shared_d, $text_d, $data_stack_d);;\
\
            readingsBulkUpdate($hash, "timestamp", $timestamp2);;\
            readingsBulkUpdate($hash, "VSZ", $vsz2);;\
            readingsBulkUpdate($hash, "RSS", $rss2);;\
            readingsBulkUpdate($hash, "Shared", $shared2);;\
            readingsBulkUpdate($hash, "Text", $text2);;\
            readingsBulkUpdate($hash, "Data_Stack", $data_stack2);;\
            \
            readingsBulkUpdate($hash, "timestamp_diff", $timestamp_d);;\
            readingsBulkUpdate($hash, "VSZ_diff", $vsz_d);;\
            readingsBulkUpdate($hash, "RSS_diff", $rss_d);;\
            readingsBulkUpdate($hash, "Shared_diff", $shared_d);;\
            readingsBulkUpdate($hash, "Text_diff", $text_d);;\
            readingsBulkUpdate($hash, "Data_Stack_diff", $data_stack_d);;\
        }\
    }\
Log(1, $result);;\
    #initiate profiling (again)\
    $hash->{helper}{mu} = Memory::Usage->new();;\
    $hash->{helper}{mu}->record();;\
\
    return $result;;\
}
attr memUsageDevice webCmd wert check
define TestTimer DOIF ([+:01])\
  (set memUsageDevice wert check)
setuuid TestTimer 6537ffff-f33f-467c-448a-78590974e73fc613
attr TestTimer do always
define MemUsage.log FileLog ./log/MemUsage-%Y.log memUsageDevice:VSZ:.*|memUsageDevice:VSZ_diff:.*
setuuid MemUsage.log 65380afc-f33f-467c-eaa7-81b49cb8c9d6f182
define SVG_MemUsage.log_1 SVG MemUsage.log:SVG_MemUsage.log_1:CURRENT
setuuid SVG_MemUsage.log_1 65380b1a-f33f-467c-3dea-faf8853ae1c7ad4a
define atTimer at +*00:00:01 { HttpUtils_NonblockingGet({ url=>'http://localhost:8083'.$FW_ME.'?room=all', callback=>sub($$$) { } }) }
setuuid atTimer 65380bc9-f33f-467c-8513-897547b187ebd689

3. FHEM in der CHROOT starten:
#/bin/sh

THIS_BASE="/mnt/USB"
THIS_CHROOT="$THIS_BASE/speicherleckTest"

# Check if chroot is mounted
mount | grep "$THIS_CHROOT" > /dev/null
if [ $? -ne 0 ]; then
    mount -t proc proc "$THIS_CHROOT/proc/"
    mount -t sysfs sys "$THIS_CHROOT/sys/"
    mount -o bind /dev "$THIS_CHROOT/dev/"
    mount -o bind /dev/pts "$THIS_CHROOT/dev/pts"
fi

chroot "$THIS_CHROOT" /bin/bash -c "su -l fhem -s /bin/bash -c 'cd /opt/fhem && perl fhem.pl fhem.cfg'"

Und dann einmal pro Sekunde aufrufen:
  • Entweder mit dem atTimer auf active stellen und damit das Kommando "HttpUtils_NonblockingGet({ url=>'http://localhost:8083'.$FW_ME.'?room=all', callback=>sub($$$) { } })" ausführen, oder
  • folgende SHELL Loop ausführen: while true; do sleep 1; curl --verbose --noproxy '*' -s --max-time 10 -o - -w 'Total time: %{time_total} seconds' http://localhost:8083/fhem?room=all; done

Zu dem SVG-Plot hier noch die Logdatei:
2023-10-24_20:31:00 memUsageDevice VSZ: 45068
2023-10-24_20:31:00 memUsageDevice VSZ_diff: 148
2023-10-24_20:32:00 memUsageDevice VSZ: 45068
2023-10-24_20:32:00 memUsageDevice VSZ_diff: 0
2023-10-24_20:33:00 memUsageDevice VSZ: 45068
2023-10-24_20:33:00 memUsageDevice VSZ_diff: 0
2023-10-24_20:34:00 memUsageDevice VSZ: 45068
2023-10-24_20:34:00 memUsageDevice VSZ_diff: 0
2023-10-24_20:35:00 memUsageDevice VSZ: 45068
2023-10-24_20:35:00 memUsageDevice VSZ_diff: 0
2023-10-24_20:36:00 memUsageDevice VSZ: 45068
2023-10-24_20:36:00 memUsageDevice VSZ_diff: 0
2023-10-24_20:37:00 memUsageDevice VSZ: 45068
2023-10-24_20:37:00 memUsageDevice VSZ_diff: 0
2023-10-24_20:38:00 memUsageDevice VSZ: 45068
2023-10-24_20:38:00 memUsageDevice VSZ_diff: 0
2023-10-24_20:39:00 memUsageDevice VSZ: 45068
2023-10-24_20:39:00 memUsageDevice VSZ_diff: 0
2023-10-24_20:40:00 memUsageDevice VSZ: 45068
2023-10-24_20:40:00 memUsageDevice VSZ_diff: 0
2023-10-24_20:41:00 memUsageDevice VSZ: 45068
2023-10-24_20:41:00 memUsageDevice VSZ_diff: 0
2023-10-24_20:42:00 memUsageDevice VSZ: 45068
2023-10-24_20:42:00 memUsageDevice VSZ_diff: 0
2023-10-24_20:43:00 memUsageDevice VSZ: 45068
2023-10-24_20:43:00 memUsageDevice VSZ_diff: 0
2023-10-24_20:44:00 memUsageDevice VSZ: 45068
2023-10-24_20:44:00 memUsageDevice VSZ_diff: 0
2023-10-24_20:45:00 memUsageDevice VSZ: 45068
2023-10-24_20:45:00 memUsageDevice VSZ_diff: 0
2023-10-24_20:46:00 memUsageDevice VSZ: 45068
2023-10-24_20:46:00 memUsageDevice VSZ_diff: 0
2023-10-24_20:47:00 memUsageDevice VSZ: 45132
2023-10-24_20:47:00 memUsageDevice VSZ_diff: 64
2023-10-24_20:48:00 memUsageDevice VSZ: 46292
2023-10-24_20:48:00 memUsageDevice VSZ_diff: 1160
2023-10-24_20:49:00 memUsageDevice VSZ: 46244
2023-10-24_20:49:00 memUsageDevice VSZ_diff: -48
2023-10-24_20:50:00 memUsageDevice VSZ: 46244
2023-10-24_20:50:00 memUsageDevice VSZ_diff: 0
2023-10-24_20:51:00 memUsageDevice VSZ: 46244
2023-10-24_20:51:00 memUsageDevice VSZ_diff: 0
2023-10-24_20:52:00 memUsageDevice VSZ: 46240
2023-10-24_20:52:00 memUsageDevice VSZ_diff: -4
2023-10-24_20:53:00 memUsageDevice VSZ: 46240
2023-10-24_20:53:00 memUsageDevice VSZ_diff: 0
2023-10-24_20:54:00 memUsageDevice VSZ: 46240
2023-10-24_20:54:00 memUsageDevice VSZ_diff: 0
2023-10-24_20:55:00 memUsageDevice VSZ: 46240
2023-10-24_20:55:00 memUsageDevice VSZ_diff: 0
2023-10-24_20:56:00 memUsageDevice VSZ: 46240
2023-10-24_20:56:00 memUsageDevice VSZ_diff: 0
2023-10-24_20:57:00 memUsageDevice VSZ: 46240
2023-10-24_20:57:00 memUsageDevice VSZ_diff: 0
2023-10-24_20:58:00 memUsageDevice VSZ: 46444
2023-10-24_20:58:00 memUsageDevice VSZ_diff: 204
2023-10-24_20:59:00 memUsageDevice VSZ: 46444
2023-10-24_20:59:00 memUsageDevice VSZ_diff: 0
2023-10-24_21:00:00 memUsageDevice VSZ: 46328
2023-10-24_21:00:00 memUsageDevice VSZ_diff: -116
2023-10-24_21:01:00 memUsageDevice VSZ: 46308
2023-10-24_21:01:00 memUsageDevice VSZ_diff: -20
2023-10-24_21:02:00 memUsageDevice VSZ: 46308
2023-10-24_21:02:00 memUsageDevice VSZ_diff: 0
2023-10-24_21:03:00 memUsageDevice VSZ: 46472
2023-10-24_21:03:00 memUsageDevice VSZ_diff: 164
2023-10-24_21:04:00 memUsageDevice VSZ: 47192
2023-10-24_21:04:00 memUsageDevice VSZ_diff: 720
2023-10-24_21:05:00 memUsageDevice VSZ: 47900
2023-10-24_21:05:00 memUsageDevice VSZ_diff: 708
2023-10-24_21:06:00 memUsageDevice VSZ: 48560
2023-10-24_21:06:00 memUsageDevice VSZ_diff: 660
2023-10-24_21:07:00 memUsageDevice VSZ: 49228
2023-10-24_21:07:00 memUsageDevice VSZ_diff: 668
2023-10-24_21:08:00 memUsageDevice VSZ: 49548
2023-10-24_21:08:00 memUsageDevice VSZ_diff: 320
2023-10-24_21:09:00 memUsageDevice VSZ: 49548
2023-10-24_21:09:00 memUsageDevice VSZ_diff: 0
2023-10-24_21:10:00 memUsageDevice VSZ: 49956
2023-10-24_21:10:00 memUsageDevice VSZ_diff: 408
2023-10-24_21:11:00 memUsageDevice VSZ: 50640
2023-10-24_21:11:00 memUsageDevice VSZ_diff: 684
2023-10-24_21:12:00 memUsageDevice VSZ: 51316
2023-10-24_21:12:00 memUsageDevice VSZ_diff: 676
2023-10-24_21:13:00 memUsageDevice VSZ: 52008
2023-10-24_21:13:00 memUsageDevice VSZ_diff: 692
2023-10-24_21:14:00 memUsageDevice VSZ: 52736
2023-10-24_21:14:00 memUsageDevice VSZ_diff: 728
2023-10-24_21:15:00 memUsageDevice VSZ: 53340
2023-10-24_21:15:00 memUsageDevice VSZ_diff: 604
2023-10-24_21:16:00 memUsageDevice VSZ: 54380
2023-10-24_21:16:00 memUsageDevice VSZ_diff: 1040
2023-10-24_21:17:00 memUsageDevice VSZ: 54948
2023-10-24_21:17:00 memUsageDevice VSZ_diff: 568
2023-10-24_21:18:00 memUsageDevice VSZ: 55656
2023-10-24_21:18:00 memUsageDevice VSZ_diff: 708
2023-10-24_21:19:00 memUsageDevice VSZ: 56356
2023-10-24_21:19:00 memUsageDevice VSZ_diff: 700
2023-10-24_21:20:00 memUsageDevice VSZ: 56896
2023-10-24_21:20:00 memUsageDevice VSZ_diff: 540
2023-10-24_21:21:00 memUsageDevice VSZ: 57584
2023-10-24_21:21:00 memUsageDevice VSZ_diff: 688
2023-10-24_21:22:00 memUsageDevice VSZ: 58280
2023-10-24_21:22:00 memUsageDevice VSZ_diff: 696
2023-10-24_21:23:00 memUsageDevice VSZ: 58844
2023-10-24_21:23:00 memUsageDevice VSZ_diff: 564
2023-10-24_21:24:00 memUsageDevice VSZ: 59516
2023-10-24_21:24:00 memUsageDevice VSZ_diff: 672
2023-10-24_21:25:00 memUsageDevice VSZ: 60176
2023-10-24_21:25:00 memUsageDevice VSZ_diff: 660
2023-10-24_21:26:00 memUsageDevice VSZ: 60708
2023-10-24_21:26:00 memUsageDevice VSZ_diff: 532
2023-10-24_21:27:00 memUsageDevice VSZ: 61428
2023-10-24_21:27:00 memUsageDevice VSZ_diff: 720
2023-10-24_21:28:00 memUsageDevice VSZ: 61976
2023-10-24_21:28:00 memUsageDevice VSZ_diff: 548
2023-10-24_21:29:00 memUsageDevice VSZ: 62748
2023-10-24_21:29:00 memUsageDevice VSZ_diff: 772
2023-10-24_21:30:00 memUsageDevice VSZ: 63324
2023-10-24_21:30:00 memUsageDevice VSZ_diff: 576
2023-10-24_21:31:00 memUsageDevice VSZ: 63928
2023-10-24_21:31:00 memUsageDevice VSZ_diff: 604
2023-10-24_21:32:00 memUsageDevice VSZ: 64660
2023-10-24_21:32:00 memUsageDevice VSZ_diff: 732
2023-10-24_21:33:00 memUsageDevice VSZ: 65200
2023-10-24_21:33:00 memUsageDevice VSZ_diff: 540
2023-10-24_21:34:00 memUsageDevice VSZ: 65884
2023-10-24_21:34:00 memUsageDevice VSZ_diff: 684
2023-10-24_21:35:00 memUsageDevice VSZ: 66556
2023-10-24_21:35:00 memUsageDevice VSZ_diff: 672
2023-10-24_21:36:00 memUsageDevice VSZ: 67092
2023-10-24_21:36:00 memUsageDevice VSZ_diff: 536
2023-10-24_21:37:00 memUsageDevice VSZ: 67772
2023-10-24_21:37:00 memUsageDevice VSZ_diff: 680
2023-10-24_21:38:00 memUsageDevice VSZ: 68320
2023-10-24_21:38:00 memUsageDevice VSZ_diff: 548
2023-10-24_21:39:00 memUsageDevice VSZ: 68868
2023-10-24_21:39:00 memUsageDevice VSZ_diff: 548
2023-10-24_21:40:00 memUsageDevice VSZ: 69684
2023-10-24_21:40:00 memUsageDevice VSZ_diff: 816
2023-10-24_21:41:00 memUsageDevice VSZ: 70232
2023-10-24_21:41:00 memUsageDevice VSZ_diff: 548
2023-10-24_21:42:00 memUsageDevice VSZ: 70920
2023-10-24_21:42:00 memUsageDevice VSZ_diff: 688
2023-10-24_21:43:00 memUsageDevice VSZ: 71468
2023-10-24_21:43:00 memUsageDevice VSZ_diff: 548
2023-10-24_21:44:00 memUsageDevice VSZ: 72028
2023-10-24_21:44:00 memUsageDevice VSZ_diff: 560
2023-10-24_21:45:00 memUsageDevice VSZ: 72436
2023-10-24_21:45:00 memUsageDevice VSZ_diff: 408

Der Speicherverbrauch erhöht sich nicht stetig, wenn ich FHEMWEB über HAProxy als ReverseProxy besuche (siehe auch: https://forum.fhem.de/index.php?topic=134798.0). Das Attribut closeConn 1 bei FHEMWEB löst das (vermutete) Problem nicht.

Was denkt ihr?

Edit #1: Wenn das oben zu langwierig erscheint, sollte es eigentlich™️ genügen folgendes at-Device anzulegen und dann den FHEM Perl Prozess z.B. mit htop/top/btop zu beobachten:
define atTimer at +*00:00:01 { HttpUtils_NonblockingGet({ url=>'http://localhost:8083'.$FW_ME.'?room=all', callback=>sub($$$) { } }) }

Torxgewinde

#1
Ich habe es auch ganz einfach machen können mit @CoolTux Testserver: https://demo-fhem.cooltux.net/fhem?room=Speicherleck

defmod memory dummy
attr memory readingList wert
attr memory room Speicherleck
attr memory setList wert
attr memory stateFormat <html><pre>VSZ</pre></html>
attr memory userReadings bla:wert:.blubb {\
    return qx(cat /proc/meminfo);;\
},\
VSZ:wert:.meinVSZ {\
    return qx(cat /proc/$$/status | grep VmSize);;\
}
attr memory webCmd wert blubb:wert meinVSZ

setstate memory <html><pre>VmSize:      179564 kB\
</pre></html>
setstate memory 2023-10-28 11:02:49 VSZ VmSize:      179564 kB\

setstate memory 2023-10-28 10:58:15 bla MemTotal:       12252628 kB\
MemFree:         3115252 kB\
MemAvailable:   10602660 kB\
Buffers:          687748 kB\
Cached:          6725108 kB\
SwapCached:            0 kB\
Active:          2400984 kB\
Inactive:        6192232 kB\
Active(anon):       1996 kB\
Inactive(anon):  1180588 kB\
Active(file):    2398988 kB\
Inactive(file):  5011644 kB\
Unevictable:           0 kB\
Mlocked:               0 kB\
SwapTotal:             0 kB\
SwapFree:              0 kB\
Dirty:               132 kB\
Writeback:             0 kB\
AnonPages:       1111352 kB\
Mapped:           416616 kB\
Shmem:              2224 kB\
KReclaimable:     398648 kB\
Slab:             478860 kB\
SReclaimable:     398648 kB\
SUnreclaim:        80212 kB\
KernelStack:        6624 kB\
PageTables:         8740 kB\
NFS_Unstable:          0 kB\
Bounce:                0 kB\
WritebackTmp:          0 kB\
CommitLimit:     6126312 kB\
Committed_AS:    2666744 kB\
VmallocTotal:   34359738367 kB\
VmallocUsed:       25888 kB\
VmallocChunk:          0 kB\
Percpu:             2528 kB\
HardwareCorrupted:     0 kB\
AnonHugePages:    696320 kB\
ShmemHugePages:        0 kB\
ShmemPmdMapped:        0 kB\
FileHugePages:         0 kB\
FilePmdMapped:         0 kB\
HugePages_Total:       0\
HugePages_Free:        0\
HugePages_Rsvd:        0\
HugePages_Surp:        0\
Hugepagesize:       2048 kB\
Hugetlb:               0 kB\
DirectMap4k:      311144 kB\
DirectMap2M:    12271616 kB\
DirectMap1G:     2097152 kB\

setstate memory 2023-10-28 10:53:58 state wert blubb
setstate memory 2023-10-28 11:02:49 wert meinVSZ

defmod atTimer at +*00:00:01 { HttpUtils_NonblockingGet({ url=>'http://localhost:8083'.$FW_ME.'?room=all', callback=>sub($$$) { } }) }
attr atTimer room Speicherleck
attr atTimer webCmd active:inactive

setstate atTimer inactive
setstate atTimer 2023-10-28 11:04:07 state inactive




Du darfst diesen Dateianhang nicht ansehen.

CoolTux

Und ich habe mich schon gewundert wieso mein CheckMK angeschlagen hat.  ;D

Ich danke Dir fürs ausführliche dokumentieren.
Ein Grund könnte sein das für jeden Aufruf ein neuer Socket eröffnet wird. Ist aber eher geraten. Müssen wir mal schauen was Rudi sagt.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

rudolfkoenig

Bei diesem Test sind viele Module betroffen: fhem.pl, FHEMWEB, SVG, FileLog, at, HttpUtils, selbst Memory::Usage oder DOIF koennte dran schuld sein, und wenn wir Pech haben, dann sind gleich mehrere Module betroffen und/oder das Problem ist perl-Version abhaengig (hatten wir auch schon mehrmals).

Um die Ursache zu finden/fixen, sollten wir Anzahl der betroffenen Module reduzieren.
Kannst Du bitte folgende Testschritte durchfuehren:
- Memory:Usage nicht regelmaessig aufrufen, sondern nur am Anfang und am Ende des Testzeitraums. Bitte den gleichen Zeitraum waehlen, damit wir es vergleichen koennen, wichtig bei mehrfachen Problemen.
- als Naechstes sollte die von HttpUtils aufgerufene Seite (room) kein SVG enthalten, um SVG/FileLog auszuschliessen.
- falls immer noch Speicherloch: statt at+HttpUtils einen externen Shellscript mit wget/curl verwenden.

rudolfkoenig

Nachtrag: in der "CoolTux-Version" wurde DOIF/Memory::Usage nicht verwendet, d.h. DOIF und Memory::Usage sind nicht (bzw. nicht ausschliesslich) fuer das Problem verantwortlich.

Torxgewinde

Hi,
Klar, um Probleme mit Memory::Usage, DOIF, FileLog und SVG ausschließen zu können, alternativ folgendes Device welches nur VSZ zurückliefert. Man checkt den Wert mit dem WebCmd dann händisch, dann sind die meisten anderen Devices als Kandidaten raus:
defmod memory dummy
attr memory readingList wert
attr memory room Speicherleck
attr memory setList wert
attr memory stateFormat VSZ
attr memory userReadings VSZ:wert:.VmSize {\
return qx(cat /proc/$$/status | grep VmSize);;\
}
attr memory wert VmSize
attr memory webCmd wert VmSize

Und dann sollte man auf den Test-FHEM auch von der Shell eine Shell-Loop wie folgt laufen lassen können:
while true; do sleep 1; curl -o - http://localhost:8083/fhem?room=all; done
Schonmal danke für die Rückmeldung.

CoolTux

Ich kann eine Demoversion fertig machen welche nur minimal Konfiguration hat. Also eigentlich nur FHEM Web. Würde das helfen?
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

CoolTux

Ich habe auch die Möglichkeit unterschiedliche Perl Versionen in meine Container ein zu bauen. Aber anfangen sollten wir erstmal mit dem offiziellen Container Image.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

Torxgewinde

Vielen Dank für die Demo im Web, ich hoffe die ist genau für solche Anwendungsfälle gedacht.

Ich würde vorerst wissen wollen ob ihr das Problem bestätigen könnt.
Ein wenig Speicherleck selbst in einem produktivem System ist jetzt nicht sooo wild, ich würde einfach mit der Shell-Loop mal draufgehen und dann den Speicherverbrauch im Auge behalten. Selbst htop/btop/top reicht dafür. Falls dann das Problem bestätigt ist, dann könnten wir ggf. eine reproduzierbare Umgebung gut gebrauchen - bis dahin ist es IMHO noch nicht nötig.

CoolTux

Ich habe die Demo Umgebung mal mit Minimal Konfig ausgerollt
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

rudolfkoenig

Ich habe mit dem angehaengten Shellscript 2 Tests gemacht:
- mit einer minimalen Config (6 Definitionen), VmSize 33MB, 3600 wgets dauern 16sec. Ein wget erzeugte 5kB an Daten.
- mit einer mittelgrossen Config (180 Definitionen, 12 "befuellte" SVGs) und plotEmbed=0 (sonst sind die SVGs nicht Teil der HTML), VmSize 61MB, 3600 wgets dauern 636sec. Ein wget erzeugte 830kB an Daten.

perl Version ist 5.36.

Ich konnte kein Speicherleck feststellen.
Ich will damit nicht behaupten, dass es keins gibt, nur dass ich so keins finde.

rudolfkoenig

Mit der fhem.cfg aus dem ersten Beitrag sehe ich auch ein Speicherleck.

Durch Auskommentieren & Testen bin ich bei der folgenden fhem.cfg gelandet, wo ein Speicherloch zu beobachten ist:
define WEB FHEMWEB 8083 global
define atTimer at +*00:00:01 { HttpUtils_NonblockingGet({ url=>'http://localhost:8083/fhem?room=all', callback=>sub($$$) { } }) }

Ich sehe kein Speicherloch, wenn ich eine andere Webseite (auch FHEMWEB, aber eine andere FHEM-Instanz) mit der gleichen Methode abfrage.
Wenn das stimmt, dann ist das Problem theoretischer Natur.
Ich wuesste aber trotzdem gerne, woran es liegt.

CoolTux

Ich kann mich erinnern das es immer wieder mal Meldungen in der Vergangenheit gab bezüglich des Raums Everything. Gerade wenn auch viele Device Instanzen existierten. Dazu sollte sich im Forum noch einiges finden denke ich.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

rudolfkoenig

Nachtrag:
Mit "closeConn 1" gab es in FHEMWEB ein Speicherleck.
Das habe ich gerade gefixt.
Betraf auch alle iPhone/iPad Benutzer, da bei diesen Verbindungen closeConn per Voreinstellung 1 ist.

Torxgewinde

#14
Hallo,
Ich denke das war es! 🎉

Mit der CoolTux Demoseite habe ich diese Konfig erstellt, ein Update durchgeführt nur um sicher zu gehen und der Speicher VSZ bleibt jetzt wunderbar konstant. Ich teste nochmal weiter, aber ich glaube diese winzige Änderung SVN Changeset 28102 hat geholfen.

attr global userattr cmdIcon devStateIcon:textField-long devStateStyle icon sortby webCmd webCmdLabel:textField-long widgetOverride
attr global autoload_undefined_devices 1
attr global commandref modular
attr global dnsServer 172.30.0.10
attr global logfile ./log/fhem-%Y-%m-%d.log
attr global modpath .
attr global mseclog 1
attr global nofork 0
attr global pidfilename ./log/fhem.pid
attr global statefile ./log/fhem.save
attr global updateInBackground 1
attr global verbose 3

define WEB FHEMWEB 8083 global
setuuid WEB 653cdf50-f33f-b825-da4f-1ba83d27afec9cca
attr WEB closeConn 0

# Fake FileLog entry, to access the fhem log from FHEMWEB
define Logfile FileLog ./log/fhem-%Y-%m.log Logfile
setuuid Logfile 653cdf50-f33f-b825-7eab-1d0cde11fc776983


define eventTypes eventTypes ./log/eventTypes.txt
setuuid eventTypes 653cdf50-f33f-b825-41a1-bba9a068dc053519

# Disable this to avoid looking for new USB devices on startup
define telnetPort telnet 7072
setuuid telnetPort 653cdf51-f33f-b825-7093-3f9a398198a68cd7
define memory dummy
setuuid memory 653cf123-f33f-b825-0edc-c9ff0b7c3dd7b6bd
attr memory readingList wert
attr memory room Speicherleck
attr memory setList wert
attr memory stateFormat VSZ kB (+- deltaVSZ kB)
attr memory userReadings VSZ:wert:.meinVSZ {\
    ##return qx(cat /proc/$$/status | grep VmSize);;\
\
    my $my_read_file = sub {\
      my ($filename) = @_;;\
      my $fh;;\
      return "Error with $filename: $!" unless open($fh, '<', $filename);;\
      my $data = do { local $/;; <$fh> };;\
      close($fh);;\
      return $data;;\
    };;\
\
    my $MEM = $my_read_file->("/proc/$$/status");;\
    my ($VMZ) = $MEM =~ /^VmSize:\s+(\d+)\s+kB/m;;\
\
    return $VMZ;;\
},\
deltaVSZ:VSZ.* differential {\
    return ReadingsNum($name, "VSZ", 0);;\
},\
history {\
    my $val = ReadingsVal($name, "VSZ", "???");;\
    my $ts = ReadingsTimestamp($name, "VSZ", undef);;\
   \
    my $this = ReadingsVal($name, $reading, "");;\
    my $length = 100;;\
    my @timestampArray = split("\n", $this);;\
    my ($thisval) = $timestampArray[-1] =~ /.*:\s+(\d+)$/;;\
\
    if ($thisval eq "$val") { return;; }\
    push(@timestampArray, "$ts: $val");;\
    while ( scalar @timestampArray > $length ) { shift(@timestampArray);; }\
\
    my $serializedArray = join("\n", @timestampArray);;\
    return $serializedArray;;\
}
attr memory webCmd wert meinVSZ
define atTimer at +*00:00:01 { HttpUtils_NonblockingGet({ url=>'http://localhost:8083'.$FW_ME.'?room=all', callback=>sub($$$) { } }) }
setuuid atTimer 653cf124-f33f-b825-110f-6879025e57348267
attr atTimer room Speicherleck
attr atTimer webCmd active:inactive
define atTimer2 at +*00:01:00 set memory wert meinVSZ
setuuid atTimer2 653e7491-f33f-b825-6494-d262cceb5777b42a
attr atTimer2 alignTime 00:00
attr atTimer2 room Speicherleck
attr atTimer2 webCmd active:inactive
define myPageCounter weblink htmlCode {\
  my $counter = ReadingsNum("myPageCounter", "counter", 0);;\
\
  $counter += 1;;\
\
  fhem("setreading myPageCounter counter $counter");;\
\
  return "<fieldset><legend>myPageCounter: <a href=\"/fhem?detail=myPageCounter\">Edit</a></legend><h1>$counter</h1></fieldset>";;\
}
setuuid myPageCounter 653eca5e-f33f-b825-e9c8-0466867d66478f05
attr myPageCounter room Speicherleck

Du darfst diesen Dateianhang nicht ansehen.

Danke!

CoolTux

Sehr schön. Dann kann ich jetzt wieder die Standard Demo ausrollen?
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

Torxgewinde

Ja klar. Ich fand es sehr hilfreich um das Problem demonstrieren zu können, danke!

Die Nacht über lief ein Test (Jede Sekunde ein HTTP-Request, jede Minute den VSZ prüfen) auch durch, ohne dass der Speicherverbrauch gewachsen wäre.