Administración de memoria y límites¶
sys
incluye varias funciones para comprender y controlar el uso de la
memoria.
Recuentos de referencias¶
La implementación principal de Python (CPython) usa recuento de referencias y
recolección de basura para la administración automática de memoria. Un
objeto se marca automáticamente para ser recolectado cuando su recuento de
referencia cae a cero. Para examinar el recuento de referencia de un objeto
existente, usa getrefcount()
.
import sys
one = []
print('At start :', sys.getrefcount(one))
two = one
print('Second reference :', sys.getrefcount(one))
del two
print('After del :', sys.getrefcount(one))
El valor informado es en realidad uno más alto de lo esperado porque hay una
referencia temporal al objeto contenido por getrefcount()
.
$ python3 sys_getrefcount.py
At start : 2
Second reference : 3
After del : 2
Ver también
gc
– Control the garbage collector via the functions exposed ingc
.
Tamaño de un objeto¶
Saber cuántas referencias tiene un objeto puede ayudar a encontrar ciclos o una pérdida de memoria, pero no es suficiente para determinar qué objetos están consumiendo la mayoría de la memoria. Eso requiere conocimiento sobre cuán grandes son los objetos.
import sys
class MyClass:
pass
objects = [
[], (), {}, 'c', 'string', b'bytes', 1, 2.3,
MyClass, MyClass(),
]
for obj in objects:
print('{:>10} : {}'.format(type(obj).__name__,
sys.getsizeof(obj)))
getsizeof()
informa el tamaño de un objeto en bytes.
$ python3 sys_getsizeof.py
list : 64
tuple : 48
dict : 240
str : 50
str : 55
bytes : 38
int : 28
float : 24
type : 1056
MyClass : 56
El tamaño informado para una clase personalizada no incluye el tamaño de los valores de los atributos.
import sys
class WithoutAttributes:
pass
class WithAttributes:
def __init__(self):
self.a = 'a'
self.b = 'b'
return
without_attrs = WithoutAttributes()
print('WithoutAttributes:', sys.getsizeof(without_attrs))
with_attrs = WithAttributes()
print('WithAttributes:', sys.getsizeof(with_attrs))
Esto puede dar una falsa impresión de la cantidad de memoria que se consume.
$ python3 sys_getsizeof_object.py
WithoutAttributes: 56
WithAttributes: 56
Para una estimación más completa del espacio utilizado por una clase,
proporciona un método __sizeof__()
para calcular el valor agregando los
tamaños de los atributos de un objeto.
import sys
class WithAttributes:
def __init__(self):
self.a = 'a'
self.b = 'b'
return
def __sizeof__(self):
return object.__sizeof__(self) + \
sum(sys.getsizeof(v) for v in self.__dict__.values())
my_inst = WithAttributes()
print(sys.getsizeof(my_inst))
Esta versión agrega el tamaño base del objeto a los tamaños de todos los
atributos almacenados en el __dict__
interno.
$ python3 sys_getsizeof_custom.py
156
Recursión¶
Permitir una recursión infinita en una aplicación de Python puede introducir un
desbordamiento de pila en el propio intérprete, lo que puede provocar un
bloqueo. Para eliminar esta situación, el intérprete proporciona una forma de
controlar la profundidad máxima de recursión usando setrecursionlimit()
y
getrecursionlimit()
.
import sys
print('Initial limit:', sys.getrecursionlimit())
sys.setrecursionlimit(10)
print('Modified limit:', sys.getrecursionlimit())
def generate_recursion_error(i):
print('generate_recursion_error({})'.format(i))
generate_recursion_error(i + 1)
try:
generate_recursion_error(1)
except RuntimeError as err:
print('Caught exception:', err)
Una vez que el tamaño de la pila alcanza el límite de recursividad, el
intérprete genera una excepción RuntimeError
para que el programa tenga la
oportunidad de manejar la situación.
$ python3 sys_recursionlimit.py
Initial limit: 1000
Modified limit: 10
generate_recursion_error(1)
generate_recursion_error(2)
generate_recursion_error(3)
generate_recursion_error(4)
generate_recursion_error(5)
generate_recursion_error(6)
generate_recursion_error(7)
generate_recursion_error(8)
Caught exception: maximum recursion depth exceeded while calling
a Python object
Valores máximos¶
Junto con los valores configurables de tiempo de ejecución, sys
incluye
variables que definen los valores máximos para los tipos que varían de un
sistema a otro.
import sys
print('maxsize :', sys.maxsize)
print('maxunicode:', sys.maxunicode)
maxsize
es el tamaño máximo de una lista, diccionario, cadena u otra
estructura de datos dictada por el tipo de tamaño del intérprete C.
maxunicode
es el punto entero Unicode más grande admitido por el intérprete
como está configurado actualmente.
$ python3 sys_maximums.py
maxsize : 9223372036854775807
maxunicode: 1114111
Valores de coma flotante¶
La estructura float_info
contiene información sobre la representación de
tipo de coma flotante utilizada por el intérprete, basada en la implementación
del sistema subyacente float
.
import sys
print('Smallest difference (epsilon):', sys.float_info.epsilon)
print()
print('Digits (dig) :', sys.float_info.dig)
print('Mantissa digits (mant_dig):', sys.float_info.mant_dig)
print()
print('Maximum (max):', sys.float_info.max)
print('Minimum (min):', sys.float_info.min)
print()
print('Radix of exponents (radix):', sys.float_info.radix)
print()
print('Maximum exponent for radix (max_exp):',
sys.float_info.max_exp)
print('Minimum exponent for radix (min_exp):',
sys.float_info.min_exp)
print()
print('Max. exponent power of 10 (max_10_exp):',
sys.float_info.max_10_exp)
print('Min. exponent power of 10 (min_10_exp):',
sys.float_info.min_10_exp)
print()
print('Rounding for addition (rounds):', sys.float_info.rounds)
Estos valores dependen del compilador y del sistema subyacente. Estos ejemplos se produjeron en OS X 10.9.5 en un Intel Core i7.
$ python3 sys_float_info.py
Smallest difference (epsilon): 2.220446049250313e-16
Digits (dig) : 15
Mantissa digits (mant_dig): 53
Maximum (max): 1.7976931348623157e+308
Minimum (min): 2.2250738585072014e-308
Radix of exponents (radix): 2
Maximum exponent for radix (max_exp): 1024
Minimum exponent for radix (min_exp): -1021
Max. exponent power of 10 (max_10_exp): 308
Min. exponent power of 10 (min_10_exp): -307
Rounding for addition (rounds): 1
Ver también
- El archivo de encabezado C
float.h
para el compilador local contiene más detalles sobre esta configuración.
Valores enteros¶
La estructura int_info
contiene información sobre la representación interna
de los enteros utilizados por el intérprete.
import sys
print('Number of bits used to hold each digit:',
sys.int_info.bits_per_digit)
print('Size in bytes of C type used to hold each digit:',
sys.int_info.sizeof_digit)
Estos ejemplos se produjeron en OS X 10.9.5 en un Intel Core i7.
$ python3 sys_int_info.py
Number of bits used to hold each digit: 30
Size in bytes of C type used to hold each digit: 4
El tipo C utilizado para almacenar enteros internamente se determina cuando se
construye el intérprete. Las arquitecturas de 64 bits usan automáticamente
enteros de 30 bits de forma predeterminada, y pueden habilitarse para
arquitecturas de 32 bits con el indicador de configuración
--enable-big-digits
.
Ver también
- Build and C API Changes de Novedades en Python 3.1
Orden de bytes¶
byteorder
se establece en el orden de bytes nativo.
import sys
print(sys.byteorder)
El valor es big
para big-endian o little
para little-endian.
$ python3 sys_byteorder.py
little
Ver también
- Wikipedia: Endianness – Descripción del formato en el que se almacenan los datos de más de un byte en un ordenador.
array
ystruct
– Otros módulos que dependen del orden de bytes de los datos.float.h
– El archivo de encabezado C para el compilador local contiene más detalles sobre esta configuración.