web-dev-qa-db-ja.com

ヒープサイズを制限する方法は?

私は時々Pythonプログラムを実行前にどれだけのメモリを使用するかを決定するのが非常に難しいプログラムです。そのため、時々Python大量のRAMを割り当てると、カーネルが大幅にスワップし、実行中の他のプロセスのパフォーマンスが低下します。

このため、Pythonヒープが成長できるメモリ量を制限したいと思います。制限に達すると、プログラムは単にクラッシュする可能性があります。これを行う最善の方法は何ですか?

問題があれば、多くのコードがCythonで記述されているため、そこに割り当てられたメモリを考慮する必要があります。私は純粋なPythonソリューション(ポータブルである必要はありません)と結婚していません。そのため、Linuxで動作するものは何でも構いません。

47
carl

resource.setrlimit() を確認してください。 Unixシステムでのみ機能しますが、リソースとプロセスの子の最大ヒープサイズをresource.RLIMIT_DATAパラメーターで選択できるため、探しているもののようです。

編集:例の追加:

import resource

rsrc = resource.RLIMIT_DATA
soft, hard = resource.getrlimit(rsrc)
print 'Soft limit starts as  :', soft

resource.setrlimit(rsrc, (1024, hard)) #limit to one kilobyte

soft, hard = resource.getrlimit(rsrc)
print 'Soft limit changed to :', soft

あなたのユースケースが正確に何なのかわかりませんが、代わりにresouce.RLIMIT_STACKでスタックのサイズに制限を設ける必要がある可能性があります。この制限を超えると、SIGSEGVシグナルがプロセスに送信されます。これを処理するには、setrlimit Linux manpage で説明されている代替シグナルスタックを使用する必要があります。ただし、sigaltstackがpythonで実装されているかどうかはわかりません。そのため、この境界を越えて復旧したい場合は難しいかもしれません。

48
xitrium

limit をご覧ください。リソースクォータを設定できます。適切なカーネル設定も必要になる場合があります。

0
SpliFF

次のコードは、指定された最大常駐セットサイズにメモリを割り当てます

import resource

def set_memory_limit(memory_kilobytes):
    # ru_maxrss: peak memory usage (bytes on OS X, kilobytes on Linux)
    usage_kilobytes = lambda: resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
    rlimit_increment = 1024 * 1024
    resource.setrlimit(resource.RLIMIT_DATA, (rlimit_increment, resource.RLIM_INFINITY))

    memory_hog = []

    while usage_kilobytes() < memory_kilobytes:
        try:
            for x in range(100):
                memory_hog.append('x' * 400)
        except MemoryError as err:
            rlimit = resource.getrlimit(resource.RLIMIT_DATA)[0] + rlimit_increment
            resource.setrlimit(resource.RLIMIT_DATA, (rlimit, resource.RLIM_INFINITY))

set_memory_limit(50 * 1024)  # 50 mb

Linuxマシンでテスト済み。

0
Ariunbayar