Rag*_*ghu 22 linux fragmentation linux-kernel
有没有办法检测 Linux 上的内存碎片?这是因为在一些长时间运行的服务器上,我注意到性能下降,只有在重新启动进程后,我才能看到更好的性能。在使用 Linux 大页面支持时,我注意到更多——Linux 中的大页面是否更容易碎片化?
我/proc/buddyinfo特别看过。我想知道是否有更好的方法(不仅仅是 CLI 命令本身,任何程序或理论背景都可以)来查看它。
Tim*_*ost 12
我正在回答linux标签。我的回答仅针对Linux。
是的,大页面更容易产生碎片。内存有两种视图,一种是您的进程获得的(虚拟的),另一种是内核管理的(真实的)。任何页面越大,将它的邻居分组(并与它保持在一起)就越困难,尤其是当您的服务运行在一个系统上时,该系统还必须支持其他默认情况下分配和写入比他们更多的内存的系统实际上最终使用。
内核对(真实)授予地址的映射是私有的。用户空间将它们视为内核呈现它们的一个很好的理由,因为内核需要能够在不混淆用户空间的情况下过度使用。您的进程获得了一个很好的、连续的“迪士尼化”地址空间,可以在其中工作,而忽略了内核在幕后实际使用该内存做什么。
您在长时间运行的服务器上看到性能下降的原因很可能是因为尚未明确锁定(例如mlock()/mlockall()或posix_madvise())且一段时间内未修改的已分配块已被分页,这意味着您的服务在必须读取时会滑到磁盘。他们。修改此行为会使您的进程成为坏邻居,这就是为什么许多人将他们的 RDBMS 放在与 web/php/python/ruby/whatever 完全不同的服务器上的原因。解决这个问题的唯一方法,理智地,是减少对连续块的竞争。
当页面 A 在内存中并且页面 B 已移动到交换时,碎片才真正明显(在大多数情况下)。自然地,重新启动您的服务似乎可以“治愈”这个问题,但这只是因为内核还没有机会在其过量使用率的范围内调出进程(现在)新分配的块。
事实上,在高负载下重新启动(假设)'apache' 可能会将其他服务拥有的块直接发送到磁盘。所以是的,'apache' 会在短时间内得到改善,但 'mysql' 可能会受到影响 .. 至少直到内核让它们在仅仅缺乏足够的物理内存时受到同样的影响。
添加更多内存,或拆分要求苛刻的malloc()消费者 :) 您需要关注的不仅仅是碎片化。
尝试vmstat大致了解实际存储的内容。
要获取当前碎片索引使用:
sudo cat /sys/kernel/debug/extfrag/extfrag_index
Run Code Online (Sandbox Code Playgroud)
要对内核内存进行碎片整理,请尝试执行:
sysctl vm.compact_memory=1
Run Code Online (Sandbox Code Playgroud)
您还尝试关闭透明大页面(又名 THP)和/或禁用交换(或减少swappiness)。
为了减少用户空间碎片,您可能需要尝试不同的分配器,例如jemalloc(它具有强大的自省能力,这将使您了解分配器内部碎片的内部情况)。
您可以通过使用它重新编译您的程序或仅通过运行您的程序来切换到自定义 malloc LD_PRELOAD:(LD_PRELOAD=${JEMALLOC_PATH}/lib/libjemalloc.so.1 app
注意THP 和内存分配器之间的交互)
尽管与内存碎片稍微无关(但与内存压缩/迁移有关),但您可能希望运行多个服务实例,每个 NUMA 节点一个实例,并使用numactl.