Analyse de l'usage de la RAM pour différentes opération
Nous allons ici réaliser un monitoring de la RAM pour différentes opérations différentes.
==> à mettre aussi dans le monitoring de la RAM...
Test sur un ESP 32 :
Au démarrage :
Juste après un reset, faire :
>>> print(gc.mem_free()) # libre
106912
>>> print(gc.mem_alloc()) # utilisee
6368
>>> print(gc.mem_free()+gc.mem_alloc()) # total
111168
>>> print(gc.mem_free()/(gc.mem_free()+gc.mem_alloc())) # % libre
0.9522164
95% de la freeRAM est libre au démarrage (6K utilisé), et on dispose de plus de 100K libre.
Import du programme de monitoring de la RAM :
Ce programme utilise une librairie pour gérer l'afficheur OLED, importe plusieurs classes du module machine
, le module time
et réalise l'affichage en temps réel sous forme graphique du niveau de RAM utilisée. Ce programme utilise un list de 128 éléments qui "rollent"
>>> gc.mem_free()
102384
>>> gc.mem_alloc()
8784
>>> print(gc.mem_free()/(gc.mem_free()+gc.mem_alloc()))
0.9208405
Création d'une fonction simple
On définit la fonction suivante qui va nous servir par la suite :
import gc
lastMem=0
def memStat():
global lastMem
gc.collect()
print ("free :"+ str(gc.mem_free()))
print("used :"+ str(gc.mem_alloc()))
print("% :"+str( gc.mem_free()/(gc.mem_free()+gc.mem_alloc())))
print("delta : "+str(gc.mem_alloc()-lastMem ))
lastMem=gc.mem_alloc()
On obtient :
>>> memStat()
free :101952
used :9280
% :0.9159471
Grosso modo 0.5Ko de plus.
Pour info, ici on caste les int
en str
dans la fonction print elle-même, ce qui utilise plus de RAM que d'utiliser format()
à priori.
Et d'autre part, l'utilisation de bytes
est plus efficace que l'utilisation str
On prendra cela en compte lorsque la RAM restante sera critique.
Création d'un List
Si on crée un list
de 1000 éléments, çà donne :
>>> x=list(range(1000))
>>> memStat()
free :97744
used :13488
% :0.8780945
delta : 4048
Soit 4Ko.
Noter que si on fait :
>>> x=None
>>> memStat()
free :101856
used :9376
% :0.9150835
delta : -4176
Il y a destruction de l'objet en RAM et libération en conséquence.
Noter que si on fait directement :
print(list(range(1000)))
>>> memStat()
free :101856
used :9376
% :0.9150835
delta : -64
Il n'y a pas dans ce cas d'allocation permanente. Il y a un pic d'utilisation qui disparaît dans la foulée.
Note
Il ne faut recourir à des variables que si c'est indispensable car cela fait allocation mémoire équivalente.
Création d'un List de grande taille
>>> x=list(range(5000))
>>> memStat()
free :69040
used :42192
% :0.6198906
delta : 32720
On a + 32K ce qui semble beaucoup comparativement à un list de 1000 qui donnait que 4K.
Noter que si on fait :
>>> x=[0]*5000
>>> memStat()
free :81808
used :29424
% :0.7347438
delta : 19952
On a +20K ce qui est plus cohérent.
De plus noter que si on fait :
>>> x=[0]*10000
>>> memStat()
free :61808
used :49424
% :0.5548359
delta : 39952
On a +40K et çà 'passe' alors que list(range(10 000))
ne passe pas.
On obtient un résultat comparable avec un list de lettres :
>>> x=['A']*10000
>>> memStat()
free :61808
used :49424
% :0.5548359
delta : 39952
Warning
Par contre, attention, on a un pic à plus du double lors de ces opérations qui doit correspondre à la manip de création par micropython.
Note
Retenir qu'avec un list
de 10 000 nombres, on utilise 40K... çà va vite...