什么占用了 Linux 内存?缓存低、缓冲区低,不是虚拟机

什么占用了 Linux 内存?缓存低、缓冲区低,不是虚拟机

首先,是的,我读过LinuxAteMyRAM,这不能解释我的情况。

# free -tm
             total       used       free     shared    buffers     cached
Mem:         48149      43948       4200          0          4         75
-/+ buffers/cache:      43868       4280
Swap:        38287          0      38287
Total:       86436      43948      42488
#

如上所示,该-/+ buffers/cache:行显示内存使用率非常高。但是,从输出中top,我没有看到任何进程使用了​​超过 100 MB 的内存。

那么,什么使用了内存?

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
28078 root      18   0  327m  92m  10m S    0  0.2   0:25.06 java
31416 root      16   0  250m  28m  20m S    0  0.1  25:54.59 ResourceMonitor
21598 root     -98   0 26552  25m 8316 S    0  0.1  80:49.54 had
24580 root      16   0 24152  10m  760 S    0  0.0   1:25.87 rsyncd
 4956 root      16   0 62588  10m 3132 S    0  0.0  12:36.54 vxconfigd
26703 root      16   0  139m 7120 2900 S    1  0.0   4359:39 hrmonitor
21873 root      15   0 18764 4684 2152 S    0  0.0  30:07.56 MountAgent
21883 root      15   0 13736 4280 2172 S    0  0.0  25:25.09 SybaseAgent
21878 root      15   0 18548 4172 2000 S    0  0.0  52:33.46 NICAgent
21887 root      15   0 12660 4056 2168 S    0  0.0  25:07.80 SybaseBkAgent
17798 root      25   0 10652 4048 1160 S    0  0.0   0:00.04 vxconfigbackupd

这是运行 x84_64 Linux 的 x86_64 机器(不是普通品牌的服务器),而不是虚拟机中的容器。内核(uname -a):

Linux 2.6.16.60-0.99.1-smp #1 SMP Fri Oct 12 14:24:23 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux

内容/proc/meminfo

MemTotal:     49304856 kB
MemFree:       4066708 kB
Buffers:         35688 kB
Cached:         132588 kB
SwapCached:          0 kB
Active:       26536644 kB
Inactive:     17296272 kB
HighTotal:           0 kB
HighFree:            0 kB
LowTotal:     49304856 kB
LowFree:       4066708 kB
SwapTotal:    39206624 kB
SwapFree:     39206528 kB
Dirty:             200 kB
Writeback:           0 kB
AnonPages:      249592 kB
Mapped:          52712 kB
Slab:          1049464 kB
CommitLimit:  63859052 kB
Committed_AS:   659384 kB
PageTables:       3412 kB
VmallocTotal: 34359738367 kB
VmallocUsed:    478420 kB
VmallocChunk: 34359259695 kB
HugePages_Total:     0
HugePages_Free:      0
HugePages_Rsvd:      0
Hugepagesize:     2048 kB

df报告文件系统没有大量内存消耗tmpfs

答案1

Linux 上的内存可能是一个难以诊断和理解的奇怪问题。

在正常运行时,大多数(如果不是全部)内存都会分配给一个或另一个任务。一些将分配给当前正在运行的前台进程。一些将存储从磁盘缓存的数据。一些将保存与在特定时刻未主动执行的进程相关的数据。

Linux 中的进程有自己的虚拟地址空间(输出中的 VIRT top)。它包含与进程相关的所有数据,可以视为进程的“大小”。但是,所有内存很少成为“真实”内存映射(输出中的 RES top)的积极组成部分。RES 或常驻内存是可在该时间点直接在 RAM 中访问的数据。此外还有共享内存 (SHR)。它可以在同一进程的多个实例之间共享。因此,进程使用的内存在任何一个时间点都是 RES 加 SHR,但如果有多个进程实例使用共享内存,则使用量为 RES 加 RES 加 RES ... 加 SHR。

那么 RES 和 VIRT 之间为什么会有区别呢?当然,如果一个进程有一块已分配的内存,那么它就是已分配的内存,不是吗?不是。内存以页面形式分配,页面可以是活动的,也可以是非活动的。活动页面是 RES 中的页面。非活动页面是“其余的”。它们可以被推到一边,因为它们目前未被访问。这意味着如果内存紧张,它们可以被交换到磁盘。但它们不会直接进入磁盘。首先,它们位于缓存中。您不想一直交换,因此在应用程序和交换空间之间有一个缓冲区。当交换器选择执行不同的进程并且不同的页面变为活动和非活动时,这些缓冲区会不断变化。所有这些都发生得太快了,普通人无法跟上。

最重要的是磁盘缓冲区。不活跃的内存不仅会进入缓存,而且当该缓存交换到磁盘时,它首先会进入磁盘缓冲区,排队等待写入。所以这是混合中的第二层缓存。这些磁盘缓冲区也被系统的其他部分用于一般的 IO 缓冲。所以它们也在不断变化。

top因此,您在等中看到的要么free是机器当前状态的即时快照,要么是一段时间内的汇总统计数据。当您读取数据时,它已经过时了。

任何一个进程都可以访问大量内存,但这样做很少是明智的。无论如何,它不可能一次访问所有内存,因此它当前未查看的内存将被移至缓存,除非它被明确标记为“锁定在核心中”。

因此,应用程序“使用”的内存量和它“拥有”的内存量是完全不同的两回事。应用程序的大部分数据空间实际上位于缓存中,而不是“核心”内存中,但由于缓存大部分时间都在 RAM 中,因此它可立即使用,只需“激活”即可成为“核心”内存。除非它已被交换到磁盘,否则它需要取消交换(如果它在缓冲区中,则可能很快)。

由于该机器的高速特性以及数字总是在变化的事实,这些数字甚至可能在计算过程中发生变化,因此从用户的角度来看,永远不可能准确地说出“这是正在使用的内存量”。 meminfo 是内核提供的时间快照,但由于是内核在执行,因此它不一定显示任何一个进程内存使用情况的真实状态,因为当时没有进程在积极执行 - 它是在进程之间。

正如我所说,这一切都非常令人困惑。

但归根结底,这真的不重要。重要的不是您有多少“空闲”内存,而是您使用了多少交换空间,以及访问交换空间的频率。是交换减慢了系统速度,而不是缺少内存(尽管缺少内存会导致过度交换)。如果您有大量已使用的内存,但没有使用任何(或很少)交换空间,则一切正常。空闲内存通常并不可取,而且通常纯粹是过渡性的,因为它用于一个目的,但尚未分配给另一个目的 - 例如,它是缓存内存,并且已交换到磁盘,但尚未用于其他任何用途,或者它是磁盘缓冲区,缓冲区已刷新到磁盘,但尚未有应用程序请求将其用于缓存。

答案2

这是答案的一部分:

指定为“已使用”内存(在“free”命令中)和“分配给活动(用户)进程的内存”(在 /proc/meminfo 中)之间存在差异。好的,所以您的系统总共有 48149 MB(约 47Gb)

如果您查看 /proc/meminfo,您会看到:Inactive: 17296272 kB = (大约 16.5 Gb) - 非活动内存可能来自已终止的进程。它也可能是活动进程长时间未使用的内存。内存不会因为进程终止而“释放”。为什么?因为这需要更多工作。同一页内存可能会再次使用,因此 Linux 内核只是将数据留在“非活动”列表中,直到进程需要它为止。

本页解释了其中的一些内容。http://careers.directi.com/display/tu/Understanding+and+optimizing+Memory+utilization;阅读 Linux 内核使用的 PFRA(页框回收算法)部分:“包含在磁盘和内存缓存中且未被任何进程引用的页面应该在属于进程的用户模式地址空间的页面之前被回收” “回收”意味着将它们从“已使用”(非活动 + 活动)移出并进入“空闲”状态。

这更详细地解释了内存管理:活动列表和非活动列表如何工作,以及页面如何在它们之间移动https://www.cs.columbia.edu/~smb/classes/s06-4118/l19.pdf

我相信内核还使用了用于数据结构的内存,并且显示为“slab 1049464 kb”(~ 1 GB),但不确定这是否是单独计算的。

答案3

您是否使用过 NFS?无论哪种方式都
值得使用slabtop -o,但可能nfs_inode_cache会失控。

答案4

你应该看的数字是使用交换,输出结果为“0”,这意味着 RAM 尚未用完。只要您的系统没有交换内存,您就不必担心其他数字,因为这些数字很难解释。

编辑:好吧,看来我的回答被认为含糊不清而不是简洁。所以让我详细说明一下。

我猜这里的主要问题是解释 top/ps 的输出,它不太准确。例如,由于对同一共享库的多次使用没有按预期进行计算,请参见http://virtualthreads.blogspot.ch/2006/02/understanding-memory-usage-on-linux.html

然而,如果交换大小正好为零,则您的系统内存尚未耗尽,这是完全正确的。当然,这是一个非常粗略的说法,但对于分析系统的实际内存使用情况,top 并不是正确的选择。(如果您查看 top,至少要对 virt 或 %mem 的输出进行排序。)

也可以看看 http://elinux.org/Runtime_Memory_Measurement

相关内容