В 32-битной системе каждый из 8000000 списков, которые вы создаете, выделит 20 байтов для самого объекта списка, плюс 16 байтов для вектора элементов списка. Таким образом, вы пытаетесь выделить как минимум (20 + 16) * 8000000 = 20168000000 байт, около 20 ГБ. И это в лучшем случае, если система malloc выделяет столько памяти, сколько требуется.
Я рассчитал размер объекта списка следующим образом:
- 2 Указатели в самой структуре
PyListObject
(см. listobject.h )
- 1 Указатель и один
Py_ssize_t
для части PyObject_HEAD
объекта списка (см. object.h )
- один
Py_ssize_t
для PyObject_VAR_HEAD
(также в object.h)
Вектор элементов списка немного перераспределен, чтобы избежать необходимости изменять его размер при каждом добавлении - смотрите list_resize в listobject.c . Размеры: 0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ... Таким образом, ваши одноэлементные списки выделят место для 4 элементов.
Ваша структура данных является несколько патологическим примером, когда вы платите цену за объект списка переменного размера, не используя его - все ваши списки имеют только один элемент. Вы могли бы избежать перераспределения 12 байтов, используя кортежи вместо списков, но для дальнейшего сокращения потребления памяти вам придется использовать другую структуру данных, которая использует меньше объектов. Трудно быть более конкретным, поскольку я не знаю, чего вы пытаетесь достичь.