了解 TCMalloc 的 "Bytes released to OS (aka unmapped)" 统计
Understanding TCMalloc's "Bytes released to OS (aka unmapped)" stat
我有一个进程在启动时消耗大量内存,但在引导进程后释放了大部分内存。我在之后打印的 TCMalloc 统计信息中看到以下内容:
#012MALLOC: 16635888 ( 15.9 MiB) Bytes in use by application
#012MALLOC: + 0 ( 0.0 MiB) Bytes in page heap freelist
#012MALLOC: + 20007352 ( 19.1 MiB) Bytes in central cache freelist
#012MALLOC: + 26367680 ( 25.1 MiB) Bytes in transfer cache freelist
#012MALLOC: + 7030680 ( 6.7 MiB) Bytes in thread cache freelists
#012MALLOC: + 1978560 ( 1.9 MiB) Bytes in malloc metadata
#012MALLOC: = 72020160 ( 68.7 MiB) Actual memory used (physical + swap)
#012MALLOC: + 239607808 ( 228.5 MiB) Bytes released to OS (aka unmapped). ***
#012MALLOC: = 311627968 ( 297.2 MiB) Virtual address space used
这里我们看到有 ~228 MB“释放到 OS”,但它也表明这仍然是进程虚拟地址 space 的一部分。看到此日志记录后,使用 ps aux 看到的 VSZ 统计数据仍然很高这一事实证实了这一点。
当我 运行 使用 strace 执行同一个程序时,我可以看到:对 brk 的所有调用都在增加,并且对 munmap 的调用(根据大小)加起来不数量 mmap-ed(如上所示)。更糟糕的是,VSZ 随着时间的推移缓慢增加,因为我的进程在后台工作,日志记录显示 (***) 在记录这些统计信息时相应增加。
所以我的问题是:这个值代表什么?我的记忆有没有被释放?我能做些什么来防止这种消费增长?
这个值代表什么?
它表示 TCMalloc 已经告诉系统它不需要并且系统可以用于其他目的的内存量。
我的内存有没有被释放?
没有。 OS 已经决定,让它免费只是为了在程序需要它时再次使用它是一种浪费,并且决定在一个步骤中直接将它从一种用途切换到另一种用途,而不是经历了使其免费的两倍努力,只是不得不让它变得不免费。
我能做些什么来防止这种消费增长?
你为什么想要?如果程序以后需要内存,它只会使它更容易,最大限度地减少对系统空闲列表的争用,并且根本没有有害影响。 TCMalloc 已经告诉 OS(通过 madvise(DONTNEED)
)OS 可能会恢复内存,而 OS 已经决定释放它不是一个好主意必须在需要时再次使用它。您有充分的理由认为 OS 是错误的吗?
只需一步直接将内存从一个人转移到另一个人,比通过两个步骤释放它只是为了再次使用它要容易得多。空闲列表在负载下可能会发生争用,不使用它要简单得多。
您可以通过运行一些消耗大量内存然后终止的程序强制OS释放它。这将强制 OS 将内存转移到该进程,然后在该进程终止时释放它。但这根本不会带来任何好处,而且会付出很多努力,最终只会增加内存管理器中的争用。这里没有问题。
我有一个进程在启动时消耗大量内存,但在引导进程后释放了大部分内存。我在之后打印的 TCMalloc 统计信息中看到以下内容:
#012MALLOC: 16635888 ( 15.9 MiB) Bytes in use by application
#012MALLOC: + 0 ( 0.0 MiB) Bytes in page heap freelist
#012MALLOC: + 20007352 ( 19.1 MiB) Bytes in central cache freelist
#012MALLOC: + 26367680 ( 25.1 MiB) Bytes in transfer cache freelist
#012MALLOC: + 7030680 ( 6.7 MiB) Bytes in thread cache freelists
#012MALLOC: + 1978560 ( 1.9 MiB) Bytes in malloc metadata
#012MALLOC: = 72020160 ( 68.7 MiB) Actual memory used (physical + swap)
#012MALLOC: + 239607808 ( 228.5 MiB) Bytes released to OS (aka unmapped). ***
#012MALLOC: = 311627968 ( 297.2 MiB) Virtual address space used
这里我们看到有 ~228 MB“释放到 OS”,但它也表明这仍然是进程虚拟地址 space 的一部分。看到此日志记录后,使用 ps aux 看到的 VSZ 统计数据仍然很高这一事实证实了这一点。
当我 运行 使用 strace 执行同一个程序时,我可以看到:对 brk 的所有调用都在增加,并且对 munmap 的调用(根据大小)加起来不数量 mmap-ed(如上所示)。更糟糕的是,VSZ 随着时间的推移缓慢增加,因为我的进程在后台工作,日志记录显示 (***) 在记录这些统计信息时相应增加。
所以我的问题是:这个值代表什么?我的记忆有没有被释放?我能做些什么来防止这种消费增长?
这个值代表什么?
它表示 TCMalloc 已经告诉系统它不需要并且系统可以用于其他目的的内存量。
我的内存有没有被释放?
没有。 OS 已经决定,让它免费只是为了在程序需要它时再次使用它是一种浪费,并且决定在一个步骤中直接将它从一种用途切换到另一种用途,而不是经历了使其免费的两倍努力,只是不得不让它变得不免费。
我能做些什么来防止这种消费增长?
你为什么想要?如果程序以后需要内存,它只会使它更容易,最大限度地减少对系统空闲列表的争用,并且根本没有有害影响。 TCMalloc 已经告诉 OS(通过 madvise(DONTNEED)
)OS 可能会恢复内存,而 OS 已经决定释放它不是一个好主意必须在需要时再次使用它。您有充分的理由认为 OS 是错误的吗?
只需一步直接将内存从一个人转移到另一个人,比通过两个步骤释放它只是为了再次使用它要容易得多。空闲列表在负载下可能会发生争用,不使用它要简单得多。
您可以通过运行一些消耗大量内存然后终止的程序强制OS释放它。这将强制 OS 将内存转移到该进程,然后在该进程终止时释放它。但这根本不会带来任何好处,而且会付出很多努力,最终只会增加内存管理器中的争用。这里没有问题。