Utilisation importante de mémoire au fil du temps (memory leak)

Bonjour,

Cela fait 2 fois que je constate qu’il doit y avoir un soucis avec ce plugin car la mémoire de mon jeedom augmente petit à petit et un peu trop. Screenshot ci dessous au bout de ~15 jours:

Et lorsque je redémarre le service:

On retombe a quelque chose de normal. Dans les logs, j’ai beaucoup d’erreurs de ce type:

[2021-07-13 20:50:27][INFO] : Plusieurs PID en cours, kill PID Nr : 1270
[2021-07-13 20:51:12][ERROR] : Le cloud à été fermé par eWeLink, tentative de relance du démon.

J’imagine que je ne suis pas le seul. Une idée ?

Merci

Moi aussi j’avais ce problème que j’avais signalé.
J’ai plus ce problème en basculant tous mes sonoff sur le plugin wifilight2

Bonjour @deimosfr

Non seulement tu n’est pas le seul mais ce problème remonte aussi sur d’autres plugin’s

j’ai pour l’instant pas trouvé la raison.

Je contourne en attendant le problème par un petit scenario pour relancer le demon régulièrement.

Voila le bloc à ta charge de choisir un déclencheur pour la fréquence d’execution

	// id du plugin
	$_plugin_Id = 'ewejee';

	// charger le plugin 
	$_plugin = plugin::byId($_plugin_Id);
	if (is_object($_plugin)) {
	    	// start deamon ...
		$scenario->setLog('démarrage du plugin -------------->>> ' . $_plugin_Id);    
    		$_plugin->deamon_start(true);    
		
    }

Pour la ligne en erreur dans ton log, n’a tu pas laisser l’application ouverte sur ton tel ou un 2ième jeedom qui tourne dessus ?
Bon dimanche

Je vais faire ça comme workaround en attendant un fix.

Et non pas de deuxième app ouvert ou truc du genre. Par contre je me demande si les mises à jour du module se font bien et ne laisseraient pas de vieux process tourner…

Merci

Merci Bernard de ces précisions

çà donne des pistes

attention ton 1er lien n’est que pour les DEV

bon dimanche

Copie du message :

Bonjour,
Je voudrais signaler un bug concernant :
$buf = socket_read($socket, 1024);
socket_read() a une fuite de mémoire de quelques octets à chaque fois qu’elle est appelée.
Quand c’est dans un script, pas de souci, la mémoire est rétablie à la fin.

Par contre si elle est utilisée à l’intérieur d’un démon dans une boucle sans fin ce memory leak fini par croitre dangereusement.

De plus, au début il n’y a pas de fuite, puis au bout de quelques heures, la fuite commence pour, en plus, augmenter.

Au final le système n’a plus de mémoire et il faut relancer le démon pour revenir à la normale (cependant Jeedom semble être équipé de ce qu’il faut car il relance automatiquement le démon).

Si cela peut aider pour ceux qui auraient des pertes de mémoire

Je considère pas vraiment le sujet comme résolu mais contourné pour ma part
Je décoche donc la Solution

Bonjour @olive

merci pour ton script

je voudrais l’utiliser mais avec un control avant pour savoir si le plugin est actif ou non

Comment réagit le deamon_start si le plugin n’a pas de demon ?

peux tu m’aider ?

// id du plugin
	$_plugin_Id = 'blea';

	// charger le plugin 
	$_plugin = plugin::byId($_plugin_Id);
	if (is_object($_plugin)) {
		$scenario->setLog('status daemon du plugin : '.$_plugin_Id.' ' . $_plugin->deamon_info()['state']);
    }
1 « J'aime »

merci, marche nickel

# CODE by @OLIVE - En cours
$plugins = plugin::listPlugin();
foreach ($plugins as $plugin) {
  	$name = $plugin->getName();
  	$id = $plugin->getId();
	$deamonstat = $plugin->deamon_info()['state'];
  	//$myPlugin = plugin::byId("$id");
  	
	$scenario->setLog('>>> Traitement du demon '.$name.' ('.$deamonstat.')');  
	// charger le plugin 
	if (is_object($plugin) && $deamonstat == "ok") {
	    // start deamon ...
		$scenario->setLog('-------------->>>démarrage du demon');   
    	//$_plugin->deamon_start(true);   
    }
}

Tu peut aussi utiliser

$_plugin->isActive()

pour savoir si il est actif

toutes les commandes sont dans la "documentation"
https://jeedom.github.io/documentation/phpdoc/classes/scenario.html

1 « J'aime »

merci

# AKL 11/08/2021 - avec CODE by @OLIVE 
$plugins = plugin::listPlugin();
foreach ($plugins as $plugin) {
  	$name = $plugin->getName();
  	$id = $plugin->getId();
	$deamonstat = $plugin->deamon_info()['state'];
	$pluginactif = $plugin->isActive(); 
  	//$myPlugin = plugin::byId("$id");
	$scenario->setLog('>>> Traitement du demon '.$name.' ACTIF : '.$pluginactif.' - DEMON : '.$deamonstat);  
	// charger le plugin 
	if (is_object($plugin) && $pluginactif == 1 && $deamonstat == "ok") {
	    // start deamon ...
    	$plugin->deamon_start(true);   
        $scenario->setLog('-------------->>>démarrage du demon');   
    }
}

ou plus simplement remplacer ceci

par

$plugins = plugin::listPlugin(true);
1 « J'aime »

encore mieux, merci @Mips

autre problème:

tu tests si l’objet $plugin est bien assigné (is_object($plugin)) mais tu l’utilises avant dès les premières lignes de la boucle ce qui n’est pas logique.
Mais de toute façon $plugin sera toujours assigné puisqu’il vient du foreach
sinon les if imbriqué c’est moche…

il faut donc écrire:

foreach (plugin::listPlugin(true) as $plugin) {
	if ($plugin->deamon_info()['state'] != 'ok') continue; // if not ok, check next plugin

	$scenario->setLog('>>> Traitement du demon '.$plugin->getName());  
	// start deamon ...
	$plugin->deamon_start(true);   
	$scenario->setLog('-------------->>>démarrage du demon');
}

bien que je ne vois pas pourquoi tu veux deux logs, ca ne sert à rien.

oui en effet, merci pour l’optimisation du compte

mais j’aime bien les variables :slight_smile:

dans ce code, oui le 2ele log n’a plus d’intérêt

Bonjour,

Personnellement, j’utilise « monit » pour gérer les fuites mémoire.
Voici mon fichier de configuration pour ce plugin qui n’en fait qu’à sa tête.

/etc/monit/conf.d/ewejee

check process ewejee
   matching "^node /var/www/html/plugins/ewejee/core/js/newserver.js"
   stop program = "/home/pi/scripts/kill-ewejee.sh"
   if memory usage > 20% for 1 cycles then stop

Avec le contenu de /home/pi/scripts/kill-ewejee.sh

#!/bin/bash

kill -9 $(ps -edf | grep /var/www/html/plugins/ewejee/core/js/newserver.js | grep -v grep | grep -v nice | awk '{print $2}')

J’avoue ne pas comprendre le code en php proposé.
Il est indiqué ceci:

if ($plugin->deamon_info()['state'] != 'ok') continue;

Mais en faisant cela, si l’état du plugin n’est pas ok, alors on passe au plugin suivant. Ne serait-ce pas plutôt:

if ($plugin->deamon_info()['state'] == 'ok') continue;

Il faudrait donc écrire:

foreach (plugin::listPlugin(true) as $plugin) {
	if ($plugin->deamon_info()['state'] == 'ok') continue; // if ok, check next plugin; if not OK, we start it.

	$scenario->setLog('>>> Traitement du demon '.$plugin->getName());  
	// start deamon ...
	$plugin->deamon_start(true);   
	$scenario->setLog('-------------->>>démarrage du demon');
}

Tout dépend ce que vous voulez faire.
Mais votre code ne répond pas au même « besoin ».

Un problème par exemple: si un démon a été arrêté manuellement et que la gestion auto est désactivée, votre code va démarrer celui-ci.
Ce n’est pas sensé arriver.

C’est bien pour ce genre de problème que ce n’est pas une bonne idée de faire l’apprenti sorcier avec ce genre de script, il y a beaucoup de possibilités de tout casser.