import numpy as np
array = np.zeros((210000, 210000)) # default numpy.float64
array.nbytes
上記のコードをmacOS搭載の8GBメモリMacBookで実行しても、エラーは発生しません。しかし、Windows 10を搭載した16 GBのメモリPC、12 GBのメモリUbuntu Ubuntuラップトップ、または128 GBのメモリLinuxスーパーコンピューターで同じコードを実行すると、PythonインタープリターがMemoryErrorを発生させます。すべてのテスト環境には64ビットPython 3.6または3.7がインストールされています。
@ Martijn Pieters 'answer は正しい方向に進んでいますが、完全に正しくはありません。これはメモリ圧縮とは関係ありませんが、代わりに virtual memory と関係しています。
たとえば、マシンで次のコードを実行してみてください。
_arrays = [np.zeros((21000, 21000)) for _ in range(0, 10000)]
_
このコードは32TiBのメモリを割り当てますが、エラーは発生しません(少なくとも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
_
これは、OSが 仮想メモリのオーバーコミット に完全に対応しているためです。必要になるまで、実際にはページを物理メモリに割り当てません。それが機能する方法は:
calloc
は、使用するメモリをOSに要求します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でも、メモリ不足エラーが必ず発生します。はい、特定のOSはRAMを圧縮できますが、メモリ不足にならないレベルまでRAMを圧縮できません。