Bonjour,
L'inscription sur ce forum et les premiers messages sont modérés par un Administrateur.
Ce n'est pas très convivial mais malheureusement nécessaire suite au spam intensif de nos amis russes.
Cordialement,
Dominique

Problème mémoire ouverture fichiers

Le langage MicroPython, l'API machine (I2C, SPI, UART, Pin, etc)
Règles du forum
Vous aimez MicroPython? Nous aussi! Ces forums sont destinés aux amoureux de Python sur MicroContrôleur.
Le support se fait sur base volontaire et uniquement pour des produits officiels (pas de copie SVP).
Le forum de MicroPython.org sera une excellente référence documentaire (en anglais).

Merci de suivre les recommandations suivantes.
Pensez à:
  • Titre claire: permettant d'identifier le produit et le problème
  • Contenu complet: schema, message d'erreur, etc (tout ce qui permet d'aider à distance).
  • Fichier joint: Max 300 Ko
  • Courtoisie et précision
sensor56
Messages : 32
Inscription : jeu. 1 avr. 2021 07:14

Problème mémoire ouverture fichiers

Message par sensor56 »

Salut,

j'ai un programme de serveur en Micropython sur ESP 32 qui utilise quelques fichiers de librairies js (on parle de fichiers de quelques kb) : j'ai le résultat attendu. Par contre, j'ai un problème par moment de mémoire type "Memory Allocation failed for xxxxx bytes", notamment à la répétition du chargement du fichier ou si j'utilise une plus grosse librairie.

Je soupçonne fortement le fait que les fichiers ouverts viennent saturer la mémoire RAM. Une première option est évidemment d'utiliser que de petites librairies, ce qui est le cas en l'occurrence. Ou de mettre les libs à servir sur le raspberry pi par exemple qui fait aussi le broker MQTT du réseau local, etc. Mais j'aimerai ici me concentrer sur les possibilités d'optimiser en micropython le chargement du fichier pour ne pas saturer la RAM.

J'ai mis en entête ce qui est conseillé sur le site Micropython : https://docs.micropython.org/en/latest/ ... eption_buf

Code : Tout sélectionner

import micropython 
micropython.alloc_emergency_exception_buf()
Je fais d'autre part un gc.collect() à intervalles régulier, lorsque la gestion d'une requête est terminée. Cela a bien amélioré les choses.

Je me demande si une bonne solution se serait de pouvoir lire le fichier sans le charger totalement en mémoire, ce qui est le cas par défaut avec un f.read().

J'ai lu ici : https://www.quora.com/How-do-I-load-lar ... -in-Python
qu'on peut passer par l'iterateur plutôt que le fichier entier qui va lire ligne par ligne en faisant :

Code : Tout sélectionner

f = open("file")
for line in f:
	...
Reste à savoir si cela va fonctionner en mode binaire f = open("file", "rb") : je vais faire quelques tests pour vérifier ce que çà donne avec mesure de la RAM résiduelle aux différentes étapes.

Je suis preneur de suggestions autour de ce sujet de la saturation de la RAM par ouverture de "gros" fichiers sur carte micropython.
Avatar de l’utilisateur
Dominique
Administrateur du site
Messages : 100
Inscription : dim. 17 mai 2020 22:43

Re: Problème mémoire ouverture fichiers

Message par Dominique »

Ne serais-t'il pas plus opportun de lire le fichier par 100 octets à la fois?
De la sorte, tu pourrais aussi allouer un seul et unique buffer de 100 octets dans MicroPython... cela éviterait la fragmentation de la mémoire.

PicoWeb ne permet pas de charger des fichiers "static" (de façon optimisée) ?
Dominique, MC Hobby.
sensor56
Messages : 32
Inscription : jeu. 1 avr. 2021 07:14

Re: Problème mémoire ouverture fichiers

Message par sensor56 »

Oui, lire ligne à ligne ou par bloc d'octet, c'est probablement la bonne option.

Je trouve que la gestion des fichiers static par picoweb n'est pas optimale. Des fois il ne le renvoie pas, sans message erreur côté Micropython et non plus côté navigateur. Pour la petite histoire, j'ai commencé avec picoweb pour les fichiers statiques, puis j'ai fait "marche arrière" vers une lecture et renvoi par socket à cause de çà. De plus, la réponse reste 3 à 4 fois meilleure avec les sockets. Genre fichier en 400ms en picoweb devient du 100ms en socket.
Répondre