@ Martijn Pieters 'answer находится на правильном пути, но не совсем правильно: это не имеет ничего общего со сжатием памяти, а вместо этого связано с виртуальной памятью .
Например, попробуйте запустить на своем компьютере следующий код:
arrays = [np.zeros((21000, 21000)) for _ in range(0, 10000)]
Этот код выделяет 32 ТБ памяти, но вы не получите ошибку (по крайней мере, я этого не делал,в Linux).Если я проверяю htop, я вижу следующее:
PID USER PRI NI VIRT RES SHR S CPU% MEM% TIME+ Command
31362 user 20 0 32.1T 69216 12712 S 0.0 0.4 0:00.22 python
Это потому, что ОС совершенно готова перегружать виртуальную память .На самом деле он не будет назначать страницы физической памяти, пока не понадобится.Вот как это работает:
calloc
запрашивает у ОС некоторую память для использования - ОС просматривает таблицы страниц процесса и находит кусок памяти, который она желаетназначить.Это быстрая операция, ОС просто сохраняет диапазон адресов памяти во внутренней структуре данных.
- программа записывает на один из адресов.
- ОС получает сбой страницы , в этот момент он просматривает и фактически назначает страницу физической памяти. Размер страницы обычно составляет несколько килобайт .
- ОС передает управление программе, которая продолжается, не замечая прерывания.
Создание одногоогромный массив не работает в Linux, потому что по умолчанию применяется эвристический алгоритм , чтобы выяснить, достаточно ли памяти доступно. ( спасибо @Martijn Pieters! ) Некоторые экспериментыв моей системе показывают, что для меня ядро не желает предоставлять более 0x3BAFFFFFF
байт.Однако, если я запускаю echo 1 | sudo tee /proc/sys/vm/overcommit_memory
, а затем снова пытаюсь запустить программу в OP, она работает нормально.
Для развлечения попробуйте запустить arrays = [np.ones((21000, 21000)) for _ in range(0, 10000)]
.Вы обязательно получите ошибку нехватки памяти, даже на MacO или Linux с компрессией подкачки.Да, некоторые операционные системы могут сжимать оперативную память, но они не могут сжимать ее до уровня, при котором у вас не будет исчерпано памяти.