Я пытаюсь сделать список с 2 поднятыми до 30 элементами, но я получаю ошибку памяти. Почему так? Является ли это за пределами максимального предела списка в python?Ошибка памяти списка Python
m=[None]*(2**30)
Я пытаюсь сделать список с 2 поднятыми до 30 элементами, но я получаю ошибку памяти. Почему так? Является ли это за пределами максимального предела списка в python?Ошибка памяти списка Python
m=[None]*(2**30)
Да, есть предел того, сколько элементов списка Python может содержать, см sys.maxsize
. Однако вы его не ударили; очень мало машин имеют достаточно памяти, чтобы удержать это много предметов.
Вы пытаетесь создать список с 1073741824 ссылками; каждая ссылка также занимает память. Это зависит от вашей ОС, сколько, но обычно это будет 4 байта для 32-битной системы, 8 байт для 64-битной ОС, где 2^30 элементов будут занимать 4 ГБ или 8 ГБ памяти, только для список ссылок.
4GB плюс другие элементы уже легко больше, чем большинство современных операционных систем позволяют использовать один процесс в памяти.
На моем Mac OS X машины (с использованием 64-битной ОС), sys.maxsize
равно 2^63, а также ссылки на объекты Python в списке займет 8 байт:
>>> import sys
>>> sys.maxsize
9223372036854775807
>>> sys.maxsize.bit_length()
63
>>> sys.getsizeof([]) # empty list overhead
72
>>> sys.getsizeof([None]) - sys.getsizeof([]) # size of one reference
8
Таким образом, чтобы создать список с sys.maxsize
элементов вам понадобится 64 exbibytes памяти, только для справки. Это больше, чем адрес 64-разрядного компьютера (practical maximum is about 16 exbibytes).
Все это игнорирует объем памяти, который будут иметь объекты, на которые вы ссылаетесь в списке. None
- синглтон, поэтому он будет фиксировать только фиксированный объем памяти. Но предположительно вы собирались хранить что-то еще в этом списке, и в этом случае вам тоже нужно учитывать это.
И вообще говоря, вы никогда не должны нуждаетесь в, чтобы создать такой большой список. Используйте разные методы; создайте разреженную структуру, используя словарь, например, я сомневаюсь, что вы планируете обращаться ко всем этим 2^30 индексам непосредственно в свой алгоритм.
Вы пытаетесь создать огромный список здесь, и у вас недостаточно свободной памяти для этого. Сколько оперативной памяти вам понадобится?
Это будет примерно 8Gb на моей машине. Вы можете найти размер None на вашей машине:
import sys
sys.getsizeof(None) # 16 here
Но для списка вы можете приблизить это следующим образом:
sys.getsizeof([None] * (2**20)) # 8388680
и надеясь, что для 2**30
это займет примерно 2**10
раза больше вы будете в конечном итоге с 8388680 * 2**10
, который составляет приблизительно 8 ГБ.
'None' - это одноэлементный, только один будет * один * такой объект, берущий эти 16 байт. Вы можете создать столько ссылок на него, сколько хотите, это * ссылки *, которые берут память. Ссылка на 64-разрядную машину обычно составляет 8 байтов, в зависимости от ОС. –
Не знал этого. Спасибо, что указал на проблему. Обновлен ответ. –