it-swarm.com.de

Wie kann ich die Heap-Größe begrenzen?

Ich schreibe manchmal Python-Programme, die sehr schwer zu bestimmen sind, wie viel Speicher sie vor der Ausführung benötigen. Daher rufe ich manchmal ein Python-Programm auf, das versucht, riesige Mengen von RAM zuzuordnen, was dazu führt, dass der Kernel stark wechselt und die Leistung anderer laufender Prozesse beeinträchtigt.

Aus diesem Grund möchte ich einschränken, wie viel Speicher ein Python-Heap vergrößern kann. Wenn das Limit erreicht ist, kann das Programm einfach abstürzen. Was ist der beste Weg dies zu tun? 

Wenn es darauf ankommt, wird viel Code in Cython geschrieben, daher sollte der dort zugewiesene Speicher berücksichtigt werden. Ich bin nicht mit einer reinen Python-Lösung verheiratet (sie muss nicht portabel sein), daher ist alles, was unter Linux funktioniert, in Ordnung.

46
carl

Check out resource.setrlimit () . Es funktioniert nur auf Unix-Systemen, scheint jedoch das zu sein, wonach Sie suchen, da Sie mit dem Parameter resource.RLIMIT_DATA eine maximale Größe des Heapspeichers für Ihren Prozess und die Kinder Ihres Prozesses auswählen können.

BEARBEITEN: Ein Beispiel hinzufügen:

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

Ich bin nicht sicher, was Ihr Anwendungsfall genau ist, aber es ist möglich, dass Sie stattdessen mit resouce.RLIMIT_STACK ein Limit für die Größe des Stapels festlegen. Wenn Sie diesen Grenzwert überschreiten, wird ein SIGSEGV-Signal an Ihren Prozess gesendet. Um dies zu erreichen, müssen Sie einen alternativen Signalstack verwenden, wie in der Linux manpage von setrlimit beschrieben. Ich bin mir nicht sicher, ob Sigaltstack in Python implementiert ist. Das könnte sich als schwierig erweisen, wenn Sie sich von dieser Grenze erholen möchten.

47
xitrium

Schau mal bei ulimit . Damit können Ressourcenkontingente festgelegt werden. Möglicherweise benötigen Sie auch entsprechende Kerneleinstellungen.

0
SpliFF

Der folgende Code weist Speicher für die angegebene maximale Größe des residenten Satzes zu.

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

Getestet auf Linux-Maschine.

0
Ariunbayar