Fuite de mémoire dans mon plugin SMA_SunnyBoy - Help

Bonjour!

Depuis un bon moment mon Jeedom a une ‹ fuite › de mémoire, comme j’ai expliqué ici et où j’ai aussi trouvé la cause (à 99%):
https://community.jeedom.com/t/fuite-memoire-besoin-daide/120882/32

Comme dis, je pense qu’il y a un problème dans le code php de la classe ‹ SMA_SunnyBoy.class.php › de mon plugin … surement un truc que je gère mal …
Je ne trouve pas cette cause et j’apprecierai si un développeur pouvait y jetter un coup d’oeil. (le code n’est pas grand)
Le plugin est sur le market.

Merci tout plein!

Sébastien

Salut,

Ton repo n’est pas publique? plus simple pour y jeter un oeil que le market :wink:

une piste :

Merci @bernardfr.caron pour la piste mais je n’utilise pas ça dans mon plugin.
Uniquement des requêtes CURL … mais je ne cois pas où je ne ferme pas une session our quoi que ce soit d’autre…

Salut @Mips ,

Si c’est publique, just ici:
https://github.com/Sattaz/Jeedom_SMA_Sunny_Boy

Salut @Sattaz
Essaie de désactiver ton démon et/ou augmenter le timer

@cstan77 , comment ca le desactiver?
Il tourne en permancence par cycle de 10 secondes, c’est justement la raison d’avoir rajoute un demon pour augmenter la frequence de rafraichissement la ou le CRON etait limite a 1 minute.
Mais comme dis, deja avant avec le CRON de 1 minute la memoire fuyait … c’est donc quelque chose dans mon code je suppose.
Il faudrait que quelqu’un de plus experimente que moi y regarde …

Merci,

Sebastien

J’ai regardé rapidement;
Y a une raison pour laquelle tu fais un sleep toi au lieu d’utiliser ce que le core propose?

dans la daemon_start tu ajoutes qlqch du style et tu ne dois plus le faire toi, le core le fera:

$cron->setDeamonSleepTime(config::byKey('pollInterval', __CLASS__, 60);

pcq dans le code du démon du coup je vois deux problèmes avec ce bout de code (je ne dis pas que c’est la cause de la fuite):

		$endtime = microtime(true);
		if ($endtime - $starttime < config::byKey('pollInterval', __CLASS__, 60, true)) {
			usleep(floor((config::byKey('pollInterval', __CLASS__) + $starttime - $endtime) * 1000000));
		}
  1. la première lecture
config::byKey('pollInterval', __CLASS__, 60, true)

ok elle force le refresh en db … mais justement ca veut dire qu’à chaque run tu forces une lecture en DB ! c’est pas dingue comme idée je trouve :wink:

  1. la deuxième
config::byKey('pollInterval', __CLASS__)

n’a plus de valeur par défaut donc vide donc en fait aucun interval si la config est mal/pas faite

et dans tous les cas le core va aussi faire un sleep / usleep (avec le délai par défaut sauf si tu le spécifies comme je proposais au début) donc t’es sauvé sur ce point (voir fichier core\php\jeeCron.php vers les lignes 95-100

hello.

premiere lecture de ton code:

L1280 curl_close ($ch);

si y’a pas d’erreur ça fait pas de curl_close à ce que je vois??

		if (curl_errno($ch)) {
			log::add('SMA_SunnyBoy', 'debug', $this->getHumanName().' -> Cannot get equipment values: '.curl_error($ch));
			$this->checkAndUpdateCmd('status', 'Erreur Données');
		} else {
          	$InverterKey = $this->get_string_between($data,'result":{"','"');
		}
		curl_close ($ch);

je le mettrais hors de la condition, puisqu’il faut close de toutes façons

@Mips , ce bout de code vient de l’exemple deamon php que j’ai tout simplement copie:

$endtime = microtime(true);
		if ($endtime - $starttime < config::byKey('pollInterval', __CLASS__, 60, true)) {
			usleep(floor((config::byKey('pollInterval', __CLASS__) + $starttime - $endtime) * 1000000));
		}

J’ai pas tout compris de tes explications, tu dis que je dois juste mettre ceci dans le daemon_start() :

$cron->setDeamonSleepTime(config::byKey('pollInterval', __CLASS__, 60);

A la place du bloc precedent qui lui se situe dans deamon() ?

Merci !

@ddelec24, bien vu !
J’ai corrige cela, je vais observer si ca change qqchose durant le week-end.

Merci !

Je ne pense pas puisque si pas d’erreur le $ch est utilisé (et fermé) plus bas dans tous les cas donc faire ce changement va juste tout planté :wink:

Pour que ca soit plus simple, j’ai fork ton plugin et j’ai commit ici le changement que je propose: use DeamonSleepTime · Mips2648/Jeedom_SMA_Sunny_Boy@6b66b95 · GitHub

ainsi tu peux voir directement
probablement que tu peux PR directement de mon fork sur ton plugin si tu le souhaites

je n’ai pas testé n’ayant pas la matos :wink:

Salut,

@Mips , maintenant je cromprends :slight_smile:
Et cela fonctionne.

@ddelec24 , effectivement Mips a raison, j’ai alors simplement commente le ‹ close ›.

J’ai redemarrer le plugin et je verrais si la memoire se stabilise.

Merci pour vos supers conseils!
Je reviens vers vous d’ici 1 a 2 jours, le temps de voir si c’est stable ou pas.

Sebastien

Hello !

Toujours pas stable :
image

Pfff genial et maintenant ceci:

SQLSTATE[HY000] [1040] Too many connections

Une autre idee?

Merci,

Sebastien

de ce que je vois sur les forums php etc, ils conseillent d’ajouter unset($ch); juste après ton curl_close($ch);

je ne l’ai jamais fait auparavant, mais sait-on jamais tu peux toujours tester.

Merci pour te reponse @ddelec24 , je met en place de suite (maintenant que mon Jeedom a redemarre …)

Sebastien

Bonjour,

C’est une modif à faire pour PHP 8.0
curl_close ne fait plus rien.


Il faut unset le résultat de curl_init
Voir `CurlHandle` class objects replace curl handlers - PHP 8.0 • PHP.Watch

OK donc mon Jeedom en Atlas 4.3.23 n’a pas PHP 8.0 …
Donc unset n’aurait aucun effet?
Qu’est-ce qui peut faire augmenter cette memoire?
Autre question, lors d’une modification de mon code, que dois-je faire afin que les effets soient pris en compte par les equipements existants? (re-sauvegerde des equipements?, redemarrage du deamon?, desactiver/reactiver le plugin au complet?)

Sebastien

Il y a memory_get_usage(); pour cela.

log::add(__CLASS__, 'debug', "Memory_usage: ".memory_get_usage());

A disposer dans le code pour localiser la fuite.
Puis ajouter les unset() kivontbien.