Pour info, j’ai fais pas mal de test avec ChatGPT. J’ai notamment relancer le container gladys prod avec l’option suivante pour créer des snapshots.
Donc avec Gladys à l’arrêt, je suis à 4,03 Go de mémoire en utilisation.
Une fois Gladys fini de démarrée, je suis à 5,7 Go de mémoire (15h43).
Jusqu’à 16h00 je reste dans cette marge, avec seulement quelques fluctuations. Mais on voit que la mémoire se libère bien.
A 16h00 le calcul des consos / coût à bien eu lieu avec une légère hausse de la mémoire mais aussitôt libéré. Ca confirme que ce n’est pas ça. Tâches terminées.
1 minute après, je me rend sur le dashboard (je ne saurais dire si c’est le déclencheur) et pouf je suis passé instantanément à 8,82 Go : Colonne « RES » (= mémoire réservée) passe de 1748Mo à 4995Mo. => Rien ne se libère
Je te met en brut ce que me dis chatGPT, et on voit ensuite si tu veux autre chose (Conversation : ChatGPT)
Oui. Là on voit clairement ce qui se passe, et vous aviez raison depuis le début : ce n’est pas une fuite du heap JS, c’est une explosion de mémoire native (hors V8), déclenchée par une opération ponctuelle.
Je vous fais une lecture précise, factuelle, à partir du report “pic” que vous venez de fournir.
Ce que dit le report au moment du pic (preuve chiffrée)
Heap JS (V8)
"usedMemory": 252011200 ≈ 240 Mo
"externalMemory": 25243016 ≈ 24 Mo
Heap parfaitement stable, quasiment identique aux snapshots précédents.
Aucune fuite JS.
Mémoire totale du process
"rss": 6198140928 ≈ 5,77 Go
"maxRss": 6374838272 ≈ 5,93 Go
+4 Go hors heap JS apparus brutalement.
Côté Linux (/proc)
RssAnon: 5 089 920 kB ≈ 4,85 Go
RssFile: 59 392 kB
Private_Dirty: 5 090 240 kB
Mémoire anonyme privée
Non mappée fichier
Non libérée après coup
Signature typique :
allocations natives massives (malloc / new côté C/C++)
Ce que ce n’est PAS (important)
Pas :
- V8
- Garbage Collector
- Objets JS conservés
- Timers ou event loop bloqués
- Fuite “classique” Node
Vos snapshots le prouvent :
le heap reste à ~260 Mo pendant que le RSS explose à ~6 Go.
Ce que c’est (quasi certain à ce stade)
Regardons les bindings natifs chargés :
"/src/server/node_modules/duckdb/lib/binding/duckdb.node"
"/src/server/node_modules/sqlite3/lib/binding/node_sqlite3.node"
"/src/server/services/usb/.../bindings-cpp.node"
"/src/server/services/bluetooth/.../bluetooth_hci_socket.node"
Le coupable n°1 : DuckDB
C’est LE suspect principal, pour plusieurs raisons :
-
DuckDB alloue massivement en natif
-
Utilise :
- vectorized execution
- buffers columnaires
- caches intermédiaires
-
Ne rend pas toujours la mémoire à l’OS immédiatement
-
Peut monter de plusieurs Go sur une seule requête
Et surtout :
Le pic est instantané, CPU élevé, mémoire jamais redescendue
→ exactement le comportement observé.
Pourquoi ça ne redescend pas
Très important à comprendre :
Donc :
Ce n’est pas une fuite infinie
C’est une montée par paliers irréversibles
Le déclencheur probable chez vous
Vu votre setup Gladys + Energy Monitoring + historique :
-
agrégation énergétique
-
calculs temporels
-
requêtes analytiques
-
possibly :
- consolidation journalière
- agrégats par phase / device
- recalcul historique
Une requête DuckDB lourde a été lancée (cron, job interne, action UI).
C’est cohérent avec :
- le CPU qui travaille
- la montée RAM en 1 seconde
- aucune création JS visible
Confirmation absolue (si vous voulez être sûr à 100%)
Lors du prochain pic, lancez immédiatement :
docker exec gladys bash -lc '
cat /proc/1/smaps | awk "
/duckdb.node/ {f=1}
/^$/ {f=0}
f && /Rss:/ {print}
"
'
Si vous voyez des centaines de MB / GB associés à DuckDB → verdict final.
Que faire concrètement (solutions réalistes)
Option A – Limiter DuckDB (recommandée)
Dans Gladys (code) :
- limiter taille des requêtes
- éviter agrégats globaux sur historique complet
- chunker par période (jour / semaine)
Option B – Forcer un plafond mémoire Node
Ça ne règle pas la cause, mais évite l’OOM host :
-e NODE_OPTIONS="--max-old-space-size=2048 ..."
Attention : ça ne limite pas le natif, mais évite d’empiler les deux.
Option C – Redémarrage programmé (pragmatique)
Si les pics sont rares mais destructeurs :
docker restart gladys
- hebdomadaire
- ou après tâche lourde
C’est très courant pour DuckDB en prod.
Conclusion claire et nette
Vos données sont excellentes
Le diagnostic est maintenant solide
Il n’y a pas de fuite mémoire JS
La RAM est consommée par des allocations natives (DuckDB très probablement)
La mémoire ne redescend pas car elle reste dans l’arène native
Si vous voulez, prochaine étape possible :
- identifier quelle requête Gladys déclenche le pic
- ou vous aider à patcher / contourner côté Gladys (log SQL, throttle, split)
À plus tard !