我有一个使用大量内存的Python应用程序,这应该没问题,因为我用
try / except MemoryError
在循环中处理它。不幸的是,MemoryError 异常从未引发 - 在此之前,Python 已被 OOM Killer 杀死(在 Debian Linux 上)。
问题是为什么......以及我如何在 Python 中捕获错误。如果我能抓住它,我就有一个简单的缓解措施,但无一例外我无法调用我的缓解措施。
仅供参考,该应用程序正在处理视频,每帧约为 15MB numpy 对象。如果我的内存不足,我很乐意降低帧速率并重试。
我还尝试使用 psutil.available 加载每个帧时跟踪内存使用情况,但该进程被终止,仍然显示 ~350MB 为可用内存(总共 2GB)。我认为这是一个碎片问题。
因此我遇到的问题是我可以任意设置一些限制,例如如果我到达 <500MB of free memory then start again with a lower frame rate, but it all feels a bit arbitrary and not very robust. If the application or perhaps the OS or the hardware changes, I might find that next time it crashes out at 501MB remaining, or something... that's why I'd rather handle it via the MemoryError exception.
可悲的是,这似乎不是一个常见问题,“python 调用了 oom-killer 异常”只给了我两页 Google 搜索结果!大多数情况下,之前的答案是“不要使用太多内存”,这并不是很有帮助 - 就我而言,我想使用尽可能多的可用内存,但如果需要的话,我很乐意使用更少的内存。只是Python在被杀死之前不给我这样做的机会!
任何想法都非常感激。
numpy 倾向于将所有内容都放入内存中,因此您可以检查内存中可以同时容纳多少个视频文件。
import numpy as np
import sys
import math
import random
def real_size(obj):
size_bytes = sys.getsizeof(obj)
if size_bytes == 0:
return "0B"
size_name = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB")
i = int(math.floor(math.log(size_bytes, 1024)))
p = math.pow(1024, i)
s = round(size_bytes / p, 2)
return "%s %s" % (s, size_name[i])
def object_15():
"""
This creates an numpy object with ~15MB
"""
row = [random.random()] * 2080000
data = np.array(row).astype(float)
return data
def my_read_file(number_of_files):
data = object_15()
for i in range(number_of_files):
data = np.append(data, object_15())
return data
print(f'Just checking that each object has ~15MB: {real_size(object_15())}')
number_of_files = 100
print(f'Objects loaded into memory = {number_of_files}\nTotal memory_used = {real_size(my_read_file(number_of_files))}')
def object_15():
"""
This creates an numpy object with ~15MB
"""
row = [random.random()] * 2080000
data = np.array(row).astype(float)
return data
def my_read_file(number_of_files):
data = object_15()
for i in range(number_of_files):
data = np.append(data, object_15())
return data
print(f'Just checking that each object has ~15MB: {real_size(object_15())}')
number_of_files = 100
print(f'Objects loaded into memory = {number_of_files}\nTotal memory_used = {real_size(my_read_file(number_of_files))}')
根据此测试,您应该能够拥有约 100 个 numpy 对象,每个对象大小约 15MB,并且使用的空间不超过 2 GB。请调整代码并尝试满足您的特定需求/对象类型。