¿Por qué Python adopta un modelo de gestión de memoria basado en valores?
(1) Recolección de basura
⑵Recuento de referencias
(3) Mecanismo de grupo de memoria
Primero, recolección de basura:
p>
A diferencia de C++, Java y otros lenguajes, Python puede asignar valores directamente a las variables sin declarar el tipo de variable de antemano. Para Python, el tipo y la memoria del objeto se determinan en tiempo de ejecución. Es por eso que llamamos escritura dinámica a Python (aquí, simplemente podemos reducir la escritura dinámica a la asignación de direcciones de memoria de variables para determinar automáticamente la variable en tiempo de ejecución.
Escriba la variable y asigne el valor). .
En segundo lugar, recuento de referencias:
Python administra la memoria de manera similar a los objetos del kernel de Windows. Cada objeto mantiene un recuento de referencia para el par de objetos. Como se muestra en la figura (imagen de la programación central de Python)
x = 3.14
y = x
Primero creamos un objeto 3.14 y luego usamos este punto flotante La referencia del objeto se asigna a X. Dado que X es la primera referencia, este objeto de punto flotante tiene un recuento de referencia de 1. El informe y =
x crea un alias de referencia Y que apunta al mismo objeto. Descubrimos que en lugar de crear un nuevo objeto para Y, apuntamos Y al objeto flotante señalado por X, dándole un recuento de referencia de 2.
Podemos probar fácilmente el punto anterior:
La identificación de la variable A y la variable B son iguales (podemos pensar en el valor de identificación como un puntero a la variable en C) .
Citamos una imagen de otro sitio web para ilustrar este problema: para el lenguaje C, cuando creamos una variable A, solicitaremos un espacio de memoria para la variable y cambiaremos el valor de la variable.
Cuando una variable se asigna a otra variable B, solicitará un nuevo espacio de memoria para B y colocará el valor de la variable en el espacio de memoria de B. Esta es la razón por la que los punteros de A y B son inconsistentes . razón. Como se muestra:
Python, por otro lado, es diferente. De hecho, Python es similar a Javascript. Como se muestra en la figura, las variables se parecen más a etiquetas adjuntas a objetos (y referenciadas de manera similar a las definiciones). Cuando una variable está vinculada a un objeto, el recuento de referencia de la variable es 1 (hay otras situaciones que también harán que el recuento de referencia de la variable se incremente), y el sistema mantiene automáticamente estas etiquetas y determina.
Cuando el recuento de referencias de la etiqueta llegue a 0, el par se reciclará.
El tercero es el mecanismo del grupo de memoria
El mecanismo de memoria de Python es operado por la fila piramidal, -1 y -2 capas. Estas tres capas son operadas principalmente por el sistema operativo.
La capa 0 es operada por funciones de asignación y liberación de memoria como malloc y free en C.
La primera y la segunda capa son grupos de memoria, implementados por la función de interfaz de Python PyMem_Malloc. Cuando el objeto tiene menos de 256 K, esta capa puede asignar memoria directamente.
La tercera capa es la capa superior, que es nuestra operación directa de los objetos de Python;
Si se llama con frecuencia a malloc y free en C, se producirán problemas de rendimiento. Además, la asignación y liberación frecuentes de pequeños fragmentos de memoria pueden generar fragmentación de la memoria. El trabajo principal de Python aquí es el siguiente:
Si la asignación de memoria solicitada está entre 1 y 256 bytes, utilice su propio sistema de administración de memoria; de lo contrario, utilice malloc directamente.
Se seguirá llamando a Malloc para asignar memoria, pero cada vez se asignará un gran bloque de memoria de 256k.
La memoria registrada en el grupo de memoria eventualmente se reciclará al grupo de memoria y no se llamará a C libre.
Libérelo para poder usarlo la próxima vez. Para objetos simples de Python, como números y cadenas, las tuplas se copian (no se permite que las tuplas cambien) (¿copia profunda?), es decir, cuando otro
cuando la variable B se asigna a la variable A, aunque A La memoria El espacio de A y B sigue siendo el mismo, pero cuando el valor de A cambia, el espacio se reasignará a A y las direcciones de A y B ya no serán las mismas.
Utilizado para diccionarios, listas, etc.
, cambiar uno hará que el otro cambie, esto también se llama copia superficial:
Apéndice:
El recuento de referencias aumenta
Objeto creado: x =4
2. Se crean otros: y = x.
3. Pasado a la función como parámetro: foo(x)
4 Como elemento del objeto contenedor: a = [1, x, '33']<. /p>
El recuento de referencias disminuye
1. La referencia local excede su alcance. Por ejemplo, al final de la función foo(x) anterior, la referencia del objeto señalado por x es negativo 1.
2. El alias del objeto se destruye explícitamente: del x; o del y
3. El alias de un objeto se asigna a otros objetos: x=789.
4. El objeto de la ventana se elimina: my list . remove (x)
5. El objeto de la ventana en sí se destruye: del myList o el objeto de la ventana en sí se ha ido. el alcance.
Recolección de basura
1. Cuando hay partes de memoria no utilizadas, el recolector de basura las limpiará. Verificará aquellos objetos con un recuento de referencia de 0 y luego borrará su espacio en la memoria. Por supuesto, además de que el recuento de referencias sea 0, el recolector de basura también lo borrará: cuando dos objetos se refieren entre sí, sus otras referencias ya son 0.
2. El mecanismo de recolección de basura también tiene un recolector de basura cíclico para garantizar la liberación de objetos referenciados circularmente (A se refiere a B y B se refiere a A, por lo que su recuento de referencias nunca será 0).