我在python中遇到内存分配问题,这看起来很奇怪,因为我认为我的脚本应该使用常量内存。我使用子进程运行外部脚本,然后记录结果。有时脚本需要太长时间,因此我设置了超时异常。这就是我所拥有的:
class Timeout():
"""Timeout class using ALARM signal."""
class Timeout(Exception):
pass
def __init__(self, sec):
self.sec = sec
def __enter__(self):
signal.signal(signal.SIGALRM, self.raise_timeout)
signal.alarm(self.sec)
def __exit__(self, *args):
signal.alarm(0) # disable alarm
def raise_timeout(self, *args):
raise Timeout.Timeout()
def simulate(Length, Time, parameters, conditions):
args = tuple(list(np.append(parameters, np.append([Length, Time], conditions))))
cmd = './simulate.m %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s' % args
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
try:
with Timeout(2):
string = proc.stdout.read()
result = (float(re.sub(r'\*\^', 'e', string)))
except ValueError:
print "ValueError", parameters
result = np.linalg.norm(parameters) * 100.0
except Timeout.Timeout:
print "TimeoutException", parameters
result = np.linalg.norm(parameters) * 100.0
except:
print "Other Exception"
result = np.linalg.norm(parameters) * 100.0
finally:
proc.terminate()
return result
我调用它并在循环中打印结果:
iters = 0
while iters < 100000:
conditions = random_conditions()
parameters = (np.random.rand(7) * 10) - 5
length = np.random.randint(500 - 75) + 75
time = np.random.randint((7200 - 3600) * 2) + 3600
fraction = simulate(length, 7200, parameters, conditions)
if fraction <= 1.0:
print ','.join(map(lambda num: str(num), np.concatenate(([time], [length], parameters, conditions, [fraction]))))
iters += 1
大约500次尝试后,我收到内存分配错误:
Traceback (most recent call last): File "Data_Generation.py", line 27, in <module>
fraction = simulate(length, 7200, parameters, conditions) File "/home/***/Documents/Lab_Program/approximator/data_generation/simulation_utils.py", line 27, in simulate
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True) File "/usr/lib/python2.7/subprocess.py", line 710, in __init__
errread, errwrite) File "/usr/lib/python2.7/subprocess.py", line 1223, in _execute_child
self.pid = os.fork() OSError: [Errno 12] Cannot allocate memory
为什么会这样?我关闭进程并在每次迭代时打印结果。这不应该是恒定的记忆吗?它似乎发生在超时错误附近。
编辑*我尝试按照此答案中的建议杀死子进程。而不是使用proc.terminate()。它走得更远(虽然这可能只是随机的)并且遇到了同样的错误。
编辑**我以极其苛刻的方式解决了这个问题。我知道可能生成的任何进程都有一个与特定正则表达式匹配的名称。我只是使用pgkill -9 -f regex
来杀死所有未被杀死的进程。我知道这些过程不会产生孩子,所以这有点安全。如果有人对清洁解决方案有任何见解,我很乐意听到。