配列を操作する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)
したがって、質問:データに十分なメモリがあるかどうかを最初に確認し、実際に配列全体のスペースを予約する方法は?