重新启动后报告的内存使用量过高 (3 GB)

iva*_*van 5 linux memory gentoo

简要问题描述:英特尔酷睿 2 Q6600 上的 64 位 Gentoo 报告在重启后大约 8GB 总内存中使用了 3GB。该内存既不被任何进程占用,也不被缓冲区/缓存使用。

上下文:emerge在尝试从源代码构建八度音程时,OOM 终止了进程后,我首先注意到了这种行为。当系统再次响应时,仍有大约 3GB 的据称已用内存未被任何进程使用。(请注意,我不能肯定地说这真的是在开始时 - 也许我之前没有注意到。)

我尝试重新启动,因为我不熟悉 OOM 可能的问题,但据报道再次使用了内存。

然后我尝试了 Memcheck86+,它在 3246.3MB 上报告了一个“失败地址”错误(测试重复了 5 次)。我降低了 RAM 频率,错误消失了(测试重复 3 次)。

然而,在我的 Gentoo 上,3GB 一直被报告为已使用,没有明显的解释(请参阅下面的诊断报告)。

我还尝试了一个实时发行版(Parted Magic),它显然表现正常(启动后大约有数百个已用内存)。

关于可能的原因甚至解决方案的任何建议?

编辑: 我现在能够克服这个问题,但仍然无法解释。我描述了我到目前为止跟踪的内容:

  • 在单用户模式下启动时不使用 3GB 内存。
  • 启动iptables结果为 3GB 使用量,而 dmesg 报告:

    nf_conntrack:回退到 vmalloc

  • 后续停止iptables不会恢复进程,内存仍然使用。

然后我更改了内核配置,使其nf_conntrack不再是内置的,而是作为模块加载的。重新iptables启动后,在没有falling back to vmalloc消息的情况下启动,也不会消耗 3GB。

我不知道,这怎么解释。也许某些内核开发人员可以帮助解释,究竟是什么导致了这种行为?

相关报道:

在此处输入图片说明 在此处输入图片说明

小智 6

此问题可能是由于连接跟踪表和哈希表的最大大小不正确而引起的。Linux 内核尝试分配连续页面来跟踪 iptables nf_conntrack 模块的连接表。由于您没有足够的物理内存,conntrack 故障返回到 vmalloc。

该表不是基于已建立的连接动态创建的,而是基于某些内核参数完全分配的。

一些额外的症状可能是发现大量nf_conntrack:回退到 vmalloc。/var/log/messages(或/var/log/kern.log,或两者中)中的消息。

这很容易解决,只需微调您的连接轨道表并缩小其大小即可。必须根据系统使用情况进行适当的调整。如果您在此系统中运行专用网络防火墙,则连接跟踪表需要很高,但如果您只是使用 iptables 来保护它免受网络入侵,则连接跟踪表可以低得多。

有关连接跟踪调整的更多信息,请参阅https://wiki.khnet.info/index.php/Conntrack_tuning

要微调系统的值,您可以首先通过运行conntrack -L(或 /sbin/sysctl net.netfilter.nf_conntrack_count)来评估系统保持打开的连接数 。更好的是,随着时间的推移保持跟踪连接的统计数据(munin做得很好)并使用最大跟踪连接数作为基线。根据此信息,您可以相应地配置 /etc/sysctl.conf。

微调时,请确保您还查看在跟踪表中保持连接的时间。有时,由于网络配置错误或错误,conntrack 表包含虚假数据连接。例如,当服务器接收到从未关闭的 SYN 连接或客户端突然断开连接并长时间保持打开的套接字时。

其次,检查您的 conntrack 条目是否有意义。有时,由于某些网络或防火墙配置错误,conntrack 表充满了垃圾。通常这些是从未完全建立的连接的条目。例如,当服务器收到传入的连接 SYN 数据包时,可能会发生这种情况,但服务器的回复总是在网络的某个地方丢失。

当微调这些值时,运行sysctl -a | grep conntrack | grep timeout可能会提供一些见解。默认值非常保守:600(10 分钟)用于通用超时,432000(5 天)用于已建立的 TCP 连接。根据系统用途和网络行为,可能需要对这些进行微调以减少 conntrack 表中的活动连接数。这将有助于为它定义一个较低的值。

但是,请确保不要将 conntrack 表的大小缩小太多,因为这可能会产生相反的效果:连接被 iptables 丢弃,因为它们无法被跟踪,并且您将开始在日志文件中出现这样的消息:'kernel : ip_conntrack: 表已满,正在丢弃数据包。

为了确认这是否是问题,请提供以下输出:

cat /proc/sys/net/ipv4/ip_conntrack_max
cat /proc/sys/net/ipv4/netfilter/ip_conntrack_buckets
Run Code Online (Sandbox Code Playgroud)