我在 python 中使用 pygame 编写了一个拼字蜜蜂程序,它工作正常,但我一直在用 7 个单词测试它,而不是更多。
我担心,如果与 300 个单词一起使用,它可能会导致内存被填满。
请记住有 2 个数组:一个保存默认单词列表,另一个保存随机单词。
最佳答案
您真的不必担心。 Python 并不是内存消耗大到仅仅 600 个单词就会引起问题。
稍加小心,您可以直接测量内存需求。 sys.getsizeof()
function让您测量给定 Python 对象的直接内存需求(仅直接内存,而不是它引用的任何内容!)。您可以使用它来测量单个字符串:
>>> import sys
>>> sys.getsizeof("Hello!")
55
>>> sys.getsizeof("memoryfootprint")
64
确切大小取决于 Python 版本和您的操作系统。 Python 字符串对象需要基本内存量来存储大量簿记信息,然后每个字符需要 1、2 或 4 个字节,具体取决于最高的 Unicode 代码点。对于 ASCII,每个字母只有一个字节。 Python 3.7,在我的 Mac OS X 系统上使用 49 个字节作为簿记部分。
获取 Python list
对象的大小意味着您仅获取列表对象的内存需求,而不是列表“中”存储的任何内容。您可以重复将相同的对象添加到列表中,但不会得到副本,因为 Python uses references for everything ,包括列表内容。考虑到这一点。
所以让我们加载 300 个随机单词,并创建两个列表,看看需要多少内存:
>>> import random
>>> words = list(map(str.strip, open('/usr/share/dict/words'))) # big file of words, present on many computers
>>> words = random.sample(words, 300) # just use 300
>>> words[:10]
['fourer', 'tampon', 'Minyadidae', 'digallic', 'euploid', 'Mograbi', 'sketchbook', 'annul', 'ambilogy', 'outtalent']
>>> import statistics
>>> statistics.mean(map(len, words))
9.346666666666666
>>> statistics.median(map(len, words))
9.0
>>> statistics.mode(map(len, words))
10
>>> sys.getsizeof(words)
2464
>>> sum(sys.getsizeof(word) for word in words)
17504
这是一个列表,包含 300 个平均长度略超过 9 个字符的唯一单词,列表需要 2464 字节,单词本身需要 17504 字节。这甚至不到 20KB。
但是,您说,您有 2 个列表。但是第二个列表不会包含您的单词的副本,它只是对现有单词的更多引用,因此只需要另外 2464 字节,即 2KB。
对于 300 个随机英语单词,在两个列表中,您的总内存要求约为 20KB 内存。
在 8GB 的机器上,你不会有任何问题。请注意,我一次性将整个 words
文件加载到我的计算机中,然后将其剪切回 300 个随机单词。这是整个初始列表需要多少内存:
>>> words = list(map(str.strip, open('/usr/share/dict/words')))
>>> len(words)
235886
>>> sum(sys.getsizeof(word) for word in words)
13815637
>>> sys.getsizeof(words)
2007112
这大约需要 15MB 的内存,用于将近 23.6 万个单词。
如果您担心包含更多对象的大型程序,您也可以使用 tracemalloc
library获取有关内存使用的统计信息:
last = None
def display_memory_change(msg):
global last
snap = tracemalloc.take_snapshot()
statdiff, last = snap.compare_to(last, 'filename', True), snap
tot = sum(s.size for s in statdiff)
change = sum(s.size_diff for s in statdiff)
print('{:>20} (Tot: {:6.1f} MiB, Inc: {:6.1f} MiB)'.format(
msg, tot / 2 ** 20, change / 2 ** 20))
# at the start, get a baseline
tracemalloc.start()
last = tracemalloc.take_snapshot()
# create objects, run more code, etc.
display_memory_change("Some message as to what has been done")
# run some more code.
display_memory_change("Show some more statistics")
使用上面的代码来衡量阅读所有这些单词:
tracemalloc.start()
last = tracemalloc.take_snapshot()
display_memory_change("Baseline")
words = list(map(str.strip, open('/usr/share/dict/words')))
display_memory_change("Loaded words list")
输出为
Baseline (Tot: 0.0 MiB, Inc: 0.0 MiB)
Loaded words list (Tot: 15.1 MiB, Inc: 15.1 MiB)
确认我的 sys.getsizeof()
测量结果。
关于python - 在 python 中导致 outOfMemoryExeption 有多容易?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53460568/