如何在内存分配失败时中止Python进程

tri*_*tan 1 python out-of-memory

Python 可能会引发内存不足 MemoryError 异常,但是有没有办法让进程在 malloc() 返回 NULL 时终止?

我正在使用一些第三方python程序,不希望程序处理MemoryError,只是希望进程快速退出。

所以我正在寻找某种方法让 python 运行时直接终止而不发出内存错误异常。

Lif*_*lex 8

AMemoryError通常意味着解释器已经耗尽了为执行程序(函数)分配的内存。我们都知道,这MemoryErrors通常表明您的代码库中可能存在问题。

我假设你有一段贪婪的代码正在剥夺你的内存。

正如评论和泰迪的回答中提到的,您可以捕获 MemoryError 并退出程序。

import sys

try:
    # your greedy piece of code 

except MemoryError:
    sys.exit()
Run Code Online (Sandbox Code Playgroud)

另一种选择是显式使用garbage collection,这可能有助于减少MemoryError. 通过使用,gc.collect您将强制垃圾收集器释放未引用的内存。

import gc 

# your greedy piece of code 
gc.collect()
Run Code Online (Sandbox Code Playgroud)

另一种选择是考虑限制应用程序的 CPU 使用率,这可能会减轻MemoryError.

以下是参考资料:

这是一些可以修改的示例代码。

import signal 
import resource 
import os 
 
# checking time limit exceed 
def time_exceeded(signo, frame): 
    print("Time's up !") 
    raise SystemExit(1) 
 
def set_max_runtime(seconds): 
    # setting up the resource limit 
    soft, hard = resource.getrlimit(resource.RLIMIT_CPU) 
    resource.setrlimit(resource.RLIMIT_CPU, (seconds, hard)) 
    signal.signal(signal.SIGXCPU, time_exceeded) 
 
# max run time of 15 millisecond 
if __name__ == '__main__': 
    set_max_runtime(15) 
    while True: 
        pass

Run Code Online (Sandbox Code Playgroud)

如果不了解更多有关代码的信息,解决此问题并不容易。

例如,问题可能与调用数据集的函数有关,该数据集太大而无法在循环中处理

或者也许向函数添加一些线程可以解决这个问题MemoryError

还有很多未知数...

基于我关于从另一个脚本调用有问题的脚本的评论。我调查了这个并发现了0xPrateek 的答案

0xPrateek建议这样做:

import os

result = os.system('python other_script.py')
if 0 == result:
    print(" Command executed successfully")
else:
    print(" Command didn't executed successfully")
Run Code Online (Sandbox Code Playgroud)

和这个:

# Importing subprocess 
import subprocess

# Your command 
cmd = "python other_script.py"

# Starting process
process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE.PIPE)

# Getting the output and errors of the program
stdout, stderr = process.communicate()

# Printing the errors 
print(stderr)
Run Code Online (Sandbox Code Playgroud)

我不确定他的代码在您的环境中如何工作,但值得一试。

我一直在尝试MemoryErrors在 Mac 上重现问题。当我的示例不使用异常时,MemoryErrors它可以从其他脚本正常退出。如果我使用异常,事情就会变得很棘手,并使我的 MAC 不稳定。

您无法修改的第三方脚本是公开的吗?

  • @tristan您是否尝试从另一个脚本调用问题脚本?当问题脚本抛出“MemoryError”时,其他脚本应该退出。 (3认同)