0

我正在运行以下简单的脚本来熟悉一下tracemalloc

import tracemalloc
import linecache

def display_custom(snapshot):
   ...  # skipped for shorter code

tracemalloc.start()

a = [3.] * 512
b = [3.] * 513
c = [3.] * 514
d = [3.] * 515
e = [3.] * 516
f = [3.] * 517
g = [3.] * 518
h = [3.] * 519
i = [3.] * 520
j = [3.] * 521
k = [3.] * 522
l = [3.] * 523
m = [3.] * 524
n = [3.] * 525
o = [3.] * 526

snapshot = tracemalloc.take_snapshot()
display_custom(snapshot)

display_custom只是对 https://docs.python.org/3/library/tracemalloc.html 的display_top轻微修改。我得到以下输出:

Top 15 lines
#1 (Line 72): size=5264 B, count=2
    h = [3.] * 519
#2 (Line 79): size=4208 B, count=1
    o = [3.] * 526
#3 (Line 78): size=4200 B, count=1
    n = [3.] * 525
#4 (Line 77): size=4192 B, count=1
    m = [3.] * 524
#5 (Line 76): size=4184 B, count=1
    l = [3.] * 523
#6 (Line 75): size=4176 B, count=1
    k = [3.] * 522
#7 (Line 74): size=4168 B, count=1
    j = [3.] * 521
#8 (Line 73): size=4160 B, count=1
    i = [3.] * 520
#9 (Line 71): size=4144 B, count=1
    g = [3.] * 518
#10 (Line 70): size=4136 B, count=1
    f = [3.] * 517
#11 (Line 69): size=4128 B, count=1
    e = [3.] * 516
#12 (Line 68): size=4120 B, count=1
    d = [3.] * 515
#13 (Line 67): size=4112 B, count=1
    c = [3.] * 514
#14 (Line 66): size=4104 B, count=1
    b = [3.] * 513
#15 (Line 65): size=4096 B, count=1
    a = [3.] * 512
Total allocated size: 63392 B

第 72 行到底发生了什么?为什么其他更大的列表只使用一个块时使用两个块?为什么内存是5264字节?(对于具有一个块内存的所有条目,只有 8* 个元素)

下面是我用于复制的实际代码的缩短版本。我上面的代码的唯一区别是

  • 我不导入(未使用的)包,
  • 我删除了两个未使用的函数定义(不同版本的漂亮打印函数)和
  • 我删除了一些被注释掉的行。

没有其他任何变化,所以我不希望内存分配发生变化。结果类似于我之前得到的结果(但不完全相同)。

import tracemalloc
import linecache


def display_custom(snapshot, key_type='lineno', limit=10):
    snapshot = snapshot.filter_traces((
        tracemalloc.Filter(False, "<frozen importlib._bootstrap>"),
        tracemalloc.Filter(False, "<unknown>"),
    ))
    top_stats = snapshot.statistics(key_type)

    print("Top %s lines" % limit)
    for index, stat in enumerate(top_stats[:limit], 1):
        frame = stat.traceback[0]
        print("#%s (Line %s): size=%d B, count=%d"
              % (index, frame.lineno, stat.size, stat.count))
        line = linecache.getline(frame.filename, frame.lineno).strip()
        if line:
            print('    %s' % line)

    other = top_stats[limit:]
    if other:
        size = sum(stat.size for stat in other)
        print("%s other: %d B" % (len(other), size))
    total = sum(stat.size for stat in top_stats)
    print("Total allocated size: %d B" % (total))


tracemalloc.start()

a = [3.] * 512
b = [3.] * 513
c = [3.] * 514
d = [3.] * 515
e = [3.] * 516
f = [3.] * 517
g = [3.] * 518
h = [3.] * 519
i = [3.] * 520
j = [3.] * 521
k = [3.] * 522
l = [3.] * 523
m = [3.] * 524
n = [3.] * 525
o = [3.] * 526

snapshot = tracemalloc.take_snapshot()
display_custom(snapshot, limit=15)

输出是:

Top 15 lines
#1 (Line 40): size=5280 B, count=2
    j = [3.] * 521
#2 (Line 45): size=4264 B, count=2
    o = [3.] * 526
#3 (Line 44): size=4256 B, count=2
    n = [3.] * 525
#4 (Line 43): size=4192 B, count=1
    m = [3.] * 524
#5 (Line 42): size=4184 B, count=1
    l = [3.] * 523
#6 (Line 41): size=4176 B, count=1
    k = [3.] * 522
#7 (Line 39): size=4160 B, count=1
    i = [3.] * 520
#8 (Line 38): size=4152 B, count=1
    h = [3.] * 519
#9 (Line 37): size=4144 B, count=1
    g = [3.] * 518
#10 (Line 36): size=4136 B, count=1
    f = [3.] * 517
#11 (Line 35): size=4128 B, count=1
    e = [3.] * 516
#12 (Line 34): size=4120 B, count=1
    d = [3.] * 515
#13 (Line 33): size=4112 B, count=1
    c = [3.] * 514
#14 (Line 32): size=4104 B, count=1
    b = [3.] * 513
#15 (Line 31): size=4096 B, count=1
    a = [3.] * 512
Total allocated size: 63504 B
4

0 回答 0