到磁盘上的内存空间是错误的内存页,或者如果应用程序的当前内存印迹大于物理内存容量的话,那么这些过高的延迟会极大地影响应用的响应时间。
许多性能问题都是由于内存不足而引起操作系统的交换。因此,有必要利用一些工具来监视内存的使用情况, 例如,每个进程或线程的内核内存占用量,以及内核数据结构的内存使用机制及其数量和大小。与 CPU 利用情况一样, 理解操作系统和各个进程的行为对于跟踪内存短缺所引起的任何性能问题至关重要 。
一、/ proc/meminfo 与 /proc/slabinf olinux 在 /proc 文件系统中提供了可以监视系统内存资源整体利用情况的工具,即 /proc/meminfo 和 /proc/slabinfo 。 这两个文件可以捕获物理内存的状态。 /proc/meminfo 的部分显示结果如下所示 :
MemTotal: 8193720 kB MemFree: 1360188 kB Buffers: 52580 kB Cached: 5048416 kB SwapCached: 117912 kB Active: 2394100 kB Inactive: 3969480 kB Active(anon): 890840 kB Inactive(anon): 607480 kB Active(file): 1503260 kB Inactive(file): 3362000 kB Unevictable: 0 kB Mlocked: 0 kB SwapTotal: 4128760 kB SwapFree: 276380 kB Dirty: 364 kB Writeback: 0 kB AnonPages: 1144908 kB Mapped: 101328 kB Shmem: 235736 kB Slab: 321044 kB SReclaimable: 235768 kB SUnreclaim: 85276 kB KernelStack: 7392 kB PageTables: 64532 kB NFS_Unstable: 0 kB Bounce: 0 kB WritebackTmp: 0 kB CommitLimit: 8225620 kB Committed_AS: 180158196 kB VmallocTotal: 34359738367 kB VmallocUsed: 289596 kB VmallocChunk: 34359446152 kB HardwareCorrupted: 0 kB AnonHugePages: 456704 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB DirectMap4k: 10240 kB DirectMap2M: 8378368 kB [huangc@V-02-01-00860 ~]$ MemTotal: 显示了物理内存总量 。MemFree: 显示了未用内存的总量 。
Buffers: 对应于 I/O 操作的缓冲区 cache,用来给文件做缓冲大小。
Cached: 表示从磁盘上读取文件时所用的内存大,被高速缓冲储存器用的内存的大小 。
SwapCached: 表示已被换出到交换空间中的内存缓存大小,被高速缓冲储存器用的交换空间的大小,其仍然被存放在swapfile中,用来在需要的时候很快的被替换而不需要再次打开I/O端口。
Active: 在活跃使用中的缓冲或高速缓冲储存器页面文件的大小,除非非常必要否则不会被移作他用。
Inactive: 在不经常使用中的缓冲或高速缓冲储存器页面的大小,可能被用于其他用途。
SwapTotal: 表示用于交换用途的磁盘内存大小。如果基于 IA32 的系统拥有 1GB 以上的物理内存,则 HighTotal 为非零值。
HighTotal: 对应高于 860MB 的物理内存。
LowTotal: 是内核使用的内存。
Mapped: 对应于被内存映射的文件大小。
Slab: 表示为内核数据结构分配的内存。
二、ps
要获知特定进程中的内存使用情况,可以使用 ps 工具来获取每个进程的内存占用情况:
[solarflar@localhost ~]$ ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.0 52876 15652 ? Ss 8月09 2:49 /usr/lib/systemd/systemd --switched-root --system --deserialize 21 root 2 0.0 0.0 0 0 ? S 8月09 0:00 [kthreadd] root 3 0.0 0.0 0 0 ? S 8月09 0:01 [ksoftirqd/0] root 5 0.0 0.0 0 0 ? S< 8月09 0:00 [kworker/0:0H] root 8 0.0 0.0 0 0 ? S 8月09 0:00 [migration/0] root 9 0.0 0.0 0 0 ? S 8月09 0:00 [rcu_bh] root 10 0.0 0.0 0 0 ? S 8月09 0:00 [rcuob/0] root 11 0.0 0.0 0 0 ? S 8月09 0:00 [rcuob/1] root 12 0.0 0.0 0 0 ? S 8月09 0:00 [rcuob/2] root 13 0.0 0.0 0 0 ? S 8月09 0:00 [rcuob/3] root 14 0.0 0.0 0 0 ? S 8月09 0:00 [rcuob/4] ps aux 的输出结果显示了每个进程消耗系统内存的总体百分比,以及该进程的虚存印迹 (VSZ) 和当前使用的物理内存量 (RSS) 。也可以使用 top(1) 通过交互方式对进程列表进行排序,以便查看哪些进程当前消耗的内存最多,以及内存使用情况如何随着系统的运行而变化 。 当标识出需要关注的进程后,可以查看这些进程的虚址空间布局,从而获知进程当前使用内存的具体分配情况。 /proc/pid/maps 包含了进程地址空间的所有映射及其大小,其中 pid 是通过 ps(1) 或 top(1) 命令获得的特定进程 ID。 每个映射显示了被分配的地址范
(backing store)( 如果存在的话 ) 的位置。 /proc/pid/maps 本质上并不是一种性能工具; 然而, 它提供了关于内存分配状况的信息。 例如,出于性能分析的目的,可以确认在虚址空间中的 1GB 和 2GB 之间是否分配了特定数量的共享内存。可以根据前述的映射图来检查其使用情况 。 以下是关于进程 ID 30829的输出结果
:
[huangc@V-02-01-00860 ~]$ cat /proc/30829/maps 00400000-0040d000 r-xp 00000000 fd:02 6291478 /home/huangc/linux.x64/bin/hsserver 0050c000-0050d000 rw-p 0000c000 fd:02 6291478 /home/huangc/linux.x64/bin/hsserver 00a35000-02882000 rw-p 00000000 00:00 0 [heap] 3209800000-3209816000 r-xp 00000000 fd:00 1441795 /lib64/libgcc_s-4.4.7-20120601.so.1 3209816000-3209a15000 ---p 00016000 fd:00 1441795 /lib64/libgcc_s-4.4.7-20120601.so.1 3209a15000-3209a16000 rw-p 00015000 fd:00 1441795 /lib64/libgcc_s-4.4.7-20120601.so.1 3209c00000-3209ce8000 r-xp 00000000 fd:00 1709911 /usr/lib64/libstdc++.so.6.0.17 3209ce8000-3209ee8000 ---p 000e8000 fd:00 1709911 /usr/lib64/libstdc++.so.6.0.17 3209ee8000-3209ef0000 r--p 000e8000 fd:00 1709911 /usr/lib64/libstdc++.so.6.0.17 3209ef0000-3209ef2000 rw-p 000f0000 fd:00 1709911 /usr/lib64/libstdc++.so.6.0.17 3209ef2000-3209f07000 rw-p 00000000 00:00 0 3b4d600000-3b4d620000 r-xp 00000000 fd:00 1442337 /lib64/ld-2.12.so 3b4d81f