У меня есть скрипт python3
, который работает с массивами numpy.memmap
. Он записывает массив во вновь сгенерированный временный файл, расположенный в /tmp
:
import numpy, tempfile
size = 2 ** 37 * 10
tmp = tempfile.NamedTemporaryFile('w+')
array = numpy.memmap(tmp.name, dtype = 'i8', mode = 'w+', shape = size)
array[0] = 666
array[size-1] = 777
del array
array2 = numpy.memmap(tmp.name, dtype = 'i8', mode = 'r+', shape = size)
print('File: {}. Array size: {}. First cell value: {}. Last cell value: {}'.\
format(tmp.name, len(array2), array2[0], array2[size-1]))
while True:
pass
Размер HDD всего 250G. Тем не менее, каким-то образом он может генерировать 10T больших файлов в /tmp
, и соответствующий массив все еще кажется доступным. Вывод скрипта следующий:
File: /tmp/tmptjfwy8nr. Array size: 1374389534720. First cell value: 666. Last cell value: 777
Файл действительно существует и отображается как размер 10T:
$ ls -l /tmp/tmptjfwy8nr
-rw------- 1 user user 10995116277760 Dec 1 15:50 /tmp/tmptjfwy8nr
Однако весь размер /tmp
намного меньше:
$ df -h /tmp
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 235G 5.3G 218G 3% /
Процесс также делает вид, что использует виртуальную память 10T, что также невозможно. Вывод команды top
:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
31622 user 20 0 10.000t 16592 4600 R 100.0 0.0 0:45.63 python3
Насколько я понимаю, это означает, что при вызове numpy.memmap
необходимая память для всего массива не выделяется и поэтому отображаемый размер файла является фиктивным. Это в свою очередь означает, что когда я начну постепенно заполнять весь массив своими данными, в какой-то момент моя программа рухнет или мои данные будут повреждены.
Действительно, если я введу в свой код следующее:
for i in range(size):
array[i] = i
Я получаю сообщение об ошибке через некоторое время:
Bus error (core dumped)
Поэтому вопрос: как сначала проверить, действительно ли достаточно памяти для данных, а потом действительно зарезервировать место под весь массив?