2

我有一个进程在启动时会消耗大量内存,但在进程启动后会释放大部分内存。我在之后打印的 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 “释放到操作系统”,但它也表明这仍然是进程虚拟地址空间的一部分。使用 ps aux 看到的 VSZ stat 在看到此日志记录后仍然很高这一事实证实了这一点。

当我使用 strace 运行相同的程序时,我可以看到:对 brk 的所有调用都在增加,并且对 munmap 的调用(就大小而言)不等于 mmap-ed 的数量(如上所示) . 更糟糕的是,随着我的进程执行后台工作,VSZ 随着时间的推移缓慢增加,并且日志显示(***)在记录这些统计信息时相应增加。

所以我的问题是:这个值代表什么?我的记忆是否被释放了?我能做些什么来防止这种消费增长?

4

1 回答 1

1

这个值代表什么?

它代表了 TCMalloc 告诉系统它不需要并且系统可以用于其他目的的内存量。

我的记忆是否被释放了?

不。操作系统决定让它免费只是为了在程序需要时再次使用它是浪费精力,并决定在一个步骤中直接将其从一种用途切换到另一种用途,而不是通过让它免费的两倍的努力只是为了让它不能免费使用它。

我能做些什么来防止这种消费增长?

你为什么想要?如果程序稍后需要内存,它只会使程序更容易,最大限度地减少对系统空闲列表的争用,并且根本没有任何有害影响。TCMalloc 告诉操作系统(通过madvise(DONTNEED)),操作系统可能会恢复内存,并且操作系统已决定将其免费释放只是为了在需要时再次使用它并不是一个好主意。你有充分的理由认为操作系统是错误的吗?

直接将内存从一个我们转移到另一个,这比通过两个步骤来释放它只是为了让它再次使用要容易得多。免费列表可以在负载下竞争,不使用它要简单得多。

您可以通过运行一些消耗大量内存然后终止的程序来强制操作系统释放它。这将迫使操作系统将内存转换为该进程,然后在该进程终止时释放它。但这根本不会带来任何好处,而且只是为了最终增加内存管理器中的争用而付出很多努力。这里没有问题。

于 2021-06-03T21:38:31.770 回答