概要
resourceを使ってPythonで使うメモリにリミットをかけてみる。
指定メモリ以上を確保しようとするとMemory Errorで落ちるようになる。
バージョン情報
- Python 3.7.3
- psutil==5.6.3
resource.RLIMIT_DATA
resource.RLIMIT_DATAはヒープサイズの上限を設定できる。
下記は使用量を500MBに制限した例。
resource.setrlimitでresource.RLIMIT_DATAを指定し、許容するメモリの量(soft, hardのtuple)を入れる。-1は無制限。下記例ではsoftに500MBを指定してhardは-1にしている。
import resource ## 制限の実行(500MB) resource.setrlimit( resource.RLIMIT_DATA, (500 * 1024 ** 2, -1)) # 書き換わっていることを確認 print(resource.getrlimit( resource.RLIMIT_DATA)) #=> (524288000, -1)
試しにpandasで程よい容量のデータを確保してみる。
import numpy as np import pandas as pd # pandasで適当なサイズのデータを作る DATA_SIZE = 6000000 df = pd.DataFrame( np.arange(DATA_SIZE).reshape(int(DATA_SIZE / 2), 2), columns=['foo', 'bar'] ) print(df.memory_usage()) #=> Index 80 #=> foo 240000000 #=> bar 240000000 #=> dtype: int64
np.zerosで6000万行確保するとDataFrameのサイズは480MBくらいになる。もう一息。
対象はヒープサイズの容量なので実メモリの利用はもう少し多く、psコマンドで見るとvszが770MB、rssが541MBになっていた。
DATA_SIZEを6000万 → 6100万にあげて実行するとヒープサイズでも500MBを超えてトドメが刺せた。
Traceback (most recent call last): File "foo.py", line 25, in <module> df = pd.DataFrame( np.arange(DATA_SIZE).reshape(int(DATA_SIZE / 2), 2), columns=['foo', 'bar'] ) MemoryError
ちゃんとMemoryErrorになってる。めでたい。
resource.RLIMIT_AS
resource.RLIMIT_ASの意味は、The maximum area (in bytes) of address space which may be taken by the process(プロセスが確保できるアドレス空間の最大領域)。
RLIMIT_DATAの時と同じように500MBを指定してみる。
import resource ## 制限の実行(500MB) resource.setrlimit( resource.RLIMIT_AS, (500 * 1024 ** 2, -1)) # 書き換わっていることを確認 print(resource.getrlimit( resource.RLIMIT_AS)) #=> (524288000, -1)
pandasで程よい容量のデータを確保してみる。
import numpy as np import pandas as pd # pandasで適当なサイズのデータを作る DATA_SIZE = 2500000 df = pd.DataFrame( np.arange(DATA_SIZE).reshape(int(DATA_SIZE / 2), 2), columns=['foo', 'bar'] )
2500万件DataFrameを作ってpsでプロセスのメモリ使用量を見ると、vszが496MB、RSSが267MB。
もうひと押し、ということで2500万 → 2700万に増やしたらMemoryErrorになった。
改定履歴
Author: Masato Watanabe, Date: 2019-08-10, 記事投稿