Représentation mémoire

publicité
Représentation mémoire
Skander Zannad et Judicaël Courant
2014-10-07
1 Modèle mémoire
Représentation des données en mémoire :
– Relativement complexe.
– Mais on peut travailler sur un modèle relativement simple.
Notre modèle :
– Python manipule des données qu’on appelle des objets.
– Un objet est une suite de cases mémoires contiguës contenant
1. Le type de l’objet.
2. Des données propres à l’objet.
3. Des liens vers d’autres objets (adresses des autres objets).
1
Exemple :
str
[ 1 , 2 , ’ s o l e i l ’ , [42 , 17]]
a
int
list
int
dict
123
47162136380880
1
32464192
str
47162136380920
b
32461144
int
32739896
32461120
2
47162136379840
int
47162137268952
1789
47162137342672
47162137217576
str
str
soleil
t
list
int
32462152
42
32460760
list
str
47162137342720
hello
47162137342768
int
str
17
world
3 Affectation
2 Variables globales
Quand on définit des variables (globales), Modifions a :
celles-ci sont stockées dans une table appe- a = b
lée dictionnaire associant à chaque nom de
Que s’est-il passé ?
variable sa valeur :
1. On a évalué l’expression b. Le résula = 123
tat est une adresse mémoire, celle de
b = 1789
l’entier 1789.
t = [ ’ h e l l o ’ , ’ world ’ ]
2. Ce résultat est mis dans a.
str
dict
a
47162136380880
int
32739896
1789
47162136380920
32739896
str
47162136379840
b
47162137268952
str
t
list
str
47162137342720
hello
47162137342768
str
world
2
4 Expressions
str
a
a = b + 1
Pour évaluer 1789 + 1, Python construit un
nouvel objet, y met le résultat et retourne
son adresse. L’évaluation d’une expression
peut créer de nouveaux objets.
int
dict
1789
47162136380880
32739536
str
47162136380920
b
32739896
47162136379840
int
47162137268952
1789
str
str
a
t
dict
47162136380880
int
list
str
47162137342720
hello
1790
32582232
str
47162136380920
b
47162137342768
str
32739896
world
47162136379840
int
47162137268952
1789
5 Aliasing
str
t
list
str
47162137342720
hello
Deux variables peuvent représenter le
même objet :
47162137342768
str
t = [9283 , 1009]
u = t
world
On parlera d’égalité physique pour dire que
deux objets ont la même adresse mémoire.
a = b + 0
En python, elle peut se tester avec le motPython a construit un nouvel objet pour clé is («t is u» vaut ici True).
évaluer 1789 + 0. . .
Remarque : Python n’est pas très malin
dict
str
47162136383280
u
47162137247256
47162136379840
list
int
47162137247256
32739848
9283
32739824
int
str
1009
t
Cela peut avoir des conséquences inattendues :
t [0 ] = 42
# u [ 0] v a u t maintenant 4 2 . . .
3
dict
str
str
47162136383280
u
u
47162137247256
dict
47162136379840
list
int
47162137247256
32462152
42
47162136383280
47162137268952
32739824
47162136379840
int
str
47162137247256
1009
list
32739848
32739824
str
int
9283
t
t
list
32739848
Attention : deux objets peuvent avoir le
même contenu mais ne pas être physiquement égaux.
t = [9283 , 1009]
u = [9283 , 1009]
int
1009
32739824
7 Un problème d’aliasing
On parlera d’égalité structurelle. En python,
elle se teste avec le symbole «==» («t == u»
# m a t r i c e n u l l e 4∗3
vaut ici True alors que «t is u» vaut False)
A = [[0]∗3]∗4
str
u
dict
47162136383280
47162137269960
47162136379840
list
47162137246104
list
47162137246104
32739848
32739824
47162137268952
str
47162137246104
int
47162137246104
9283
list
32461168
32461168
int
32461168
0
t
list
32739848
int
1009
32739824
A [ 0 ] [ 2 ] = 42
list
6 Copier une liste
47162137246104
47162137246104
Le slicing (tranchage) se fait par copie.
C’est un moyen simple de copier une liste
dans une autre :
47162137246104
47162137246104
list
32461168
int
32461168
0
32462152
int
t = [9283 , 1009]
u = t[:]
42
4
Pour construire A correctement, on crée
une liste de 4 objets bidons :
A = [ None ]∗4
list
9653152
9653152
None
9653152
9653152
Puis on remplace chacun par une nouvelle rangée de 0.
f o r i in range ( 4 ) :
A [ i ] = [0]∗3
list
32461168
32461168
32461168
list
list
47162137246104
32461168
47162137269960
32461168
47162137299280
32461168
47162137299568
list
32461168
int
0
32461168
32461168
list
32461168
32461168
32461168
5
8 Appel de fonctions
Selon les langages de programmation, les valeurs des objets peuvent être :
– Les données contenues dans les objets manipulés (cas de Scilab)
– Les adresses en mémoire de ces objets (cas de Python)
Appel de f(t), où t tableau à n éléments :
– En Scilab, copie des n éléments : demande un temps proportionnel à n (long
quand n est grand). Impossibilité pour f de modifier le contenu de t.
– En Python, passage de l’adresse mémoire de t à f : temps constant. Possibilité pour
f de modifier le contenu de t.
6
Exemple :
int
def swap ( u , i , j ) :
u[i] , u[j] = u[j] , u[i]
t = [ 11 , 22 , 33]
swap ( t , 0 , 1)
32461168
int
32461144
1
47162137268952
Lors de l’exécution de swap, deux dictionnaires de variables : locales et globales.
str
47162135947904
list
int
32461096
3
32461072
47162137247256
int
4
NB : print(u) donne
i
dict
0
list
[0 , 1 , [3 , 4 , [ . . . ] ] ]
int
0
32461168
str
47162136381640
j
10 Ramasse-miettes
32461144
47162136383280
int
47162137299496
1
Pour exécuter
t = [ 0 , 1 , 2]
str
dict
47162137299496
Python prend de la place mémoire pour
représenter la liste :
u
47162136379840
int
list
22
32460640
32460904
int
dict
str
32460376
11
47162136379840
t
47162137299856
int
str
int
list
t
33
32461168
0
32461144
int
32461120
1
int
2
9 Graphe des données
Lors de l’exécution du programme, les
Si on affecte la variable avec une autre
données peuvent former un graphe arbi- valeur :
trairement complexe, il peut même y avoir
t = 42
des cycles.
u = [ 0 , 1 , 2]
v = [3 , 4 , u]
u [2] = v
7
dict
str
47162136379840
t
32462152
int
42
Qu’est devenue la liste [0, 1, 2] ?
– Elle n’est plus accessible depuis les
variables existantes.
– On peut libérer la place utilisée pour
la liste afin de la réutiliser pour autre
chose.
8
Récupération de la place inutilement utilisée :
– Gérée par un mécanisme interne à l’implantation de Python.
– Appelé Garbage Collector (GC), en français Glaneur de Cellules ou Ramasse-miettes.
– Le déclenchement du GC est non spécifié : il peut aussi bien se déclencher dès
qu’un objet est inaccessible qu’attendre le moment où la mémoire est pleine et où
il faut faire de la place pour de nouveaux objets.
11 Conclusion
Une bonne nouvelle : Python libère libère tout seul la mémoire qui n’est plus utilisée,
donc il n’y a (presque) pas à s’en soucier.
Une mauvaise : Quand on gère des données un peu complexes (tableaux de tableaux), il est important de comprendre la représentation des objets en mémoire pour
comprendre ce qu’il se passe.
Mais heureusement, comprendre ce qu’il se passe est facile si on apprend et qu’on
retient les deux règles d’or.
Les deux règles d’or :
1. Affecter une variable avec une expression associe la valeur de l’expression à la
variable, appeler une fonction associe la valeur des expressions données comme
arguments réels de la fonction aux variables paramètres formels de la fonction.
2. La valeur d’une expression est juste l’adresse mémoire de l’objet calculé par
l’évaluation de l’expression.
9
Téléchargement