我已经开始在我的系统上调整一点 Linux VM 性能(是的。我知道 vm.swappiness=0 会杀死小猫,但我发现 30-40 对我来说更好,因为它改善了我的延迟 - 可能以吞吐量为代价)。我想问一下 tmpfs 是如何计算的(是缓存还是程序)以便交换和vm.swappiness.
为了提供更高级别,我需要一个文件夹:
目前我使用的是普通FS。我听说(未测试)关于大型 tmpfs 在交换上推送数据的问题。由于我假设测试是在默认情况下完成的,vm.swappiness=60而 tmpfs 只是仅占用缓存,因此减少的内容vm.swappiness将使其在内存压力期间更容易交换。我对么?
当我看到有足够的内存可用时,我无法理解为什么内核会发出这个 oom 杀手:
另外为什么分配了这么多内核缓存页面?我看后说有足够的可用内存
普通的
DMA
普通自由行
这是一个基于 NAND 闪存的嵌入式设备,具有 256 MB RAM
内核:2.6.31
myshellscript invoked oom-killer: gfp_mask=0xd0, order=2, oomkilladj=0
Backtrace:
[<c0106494>] (dump_backtrace+0x0/0x110) from [<c03641a0>] (dump_stack+0x18/0x1c)
r6:000000d0 r5:c9040c60 r4:00000002 r3:c0448690
[<c0364188>] (dump_stack+0x0/0x1c) from [<c015a314>] (oom_kill_process.clone.11+0x60/0x1b4)
[<c015a2b4>] (oom_kill_process.clone.11+0x0/0x1b4) from [<c015a738>] (__out_of_memory+0x154/0x178)
r8:c21e86e0 r7:001fb000 r6:00000002 r5:000000d0 r4:c9b6e000
[<c015a5e4>] (__out_of_memory+0x0/0x178) from [<c015a980>] (out_of_memory+0x68/0xa0)
[<c015a918>] (out_of_memory+0x0/0xa0) from [<c015d230>] (__alloc_pages_nodemask+0x42c/0x520)
r5:00000002 r4:000000d0
[<c015ce04>] (__alloc_pages_nodemask+0x0/0x520) from [<c015d388>] (__get_free_pages+0x18/0x44)
[<c015d370>] (__get_free_pages+0x0/0x44) from [<c0109418>] (get_pgd_slow+0x1c/0xe0)
[<c01093fc>] (get_pgd_slow+0x0/0xe0) from [<c0129ab0>] (mm_init.clone.43+0xb0/0xf0)
r7:c90858c0 r6:00000000 r5:c90858c0 r4:ce1a6680
[<c0129a00>] (mm_init.clone.43+0x0/0xf0) from [<c0129c40>] …Run Code Online (Sandbox Code Playgroud) 在第一个 shell 上,我tail不带参数运行命令。
在第二个 shell 上,我使用 strace 杀死第一个尾部来监视系统调用。
qdii@nomada ~ $ strace kill 1713
execve("/bin/kill", ["kill", "1713"], [/* 82 vars */]) = 0
brk(0) = 0x2533000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f9dacfe8000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
Run Code Online (Sandbox Code Playgroud)
我不知道brk命令,所以我查了一下,发现它改变了进程的数据段的末尾。为什么kill要这样做?特别是将数据段设置为0似乎没有什么意义。
在Linux Kernel Development (LKD) 第 3 版,第 12 章 Zones 下,Robert Love 说:
特别是,Linux 必须解决硬件在内存寻址方面的两个缺点:
某些硬件设备只能对某些内存地址执行 DMA(直接内存访问)。
某些体系结构可以物理寻址比虚拟寻址更多的内存。因此,某些内存不会永久映射到内核地址空间。
我的问题:
但我猜测只有物理内存被映射到 KAS 中。让我知道他上面第 2 点的意思以及我在这里做出的错误假设。
我在 4 MB RAM 到 512 GB RAM 的系统上使用了 GNU/Linux。当他们开始交换时,大多数时候你仍然可以登录并终止违规进程——你只需要多 100-1000 倍的耐心。
在我的新 32 GB 系统上发生了变化:它在开始交换时阻塞。有时有完整的磁盘活动,但有时没有磁盘活动。
为了检查可能是什么问题,我编写了这个程序。这个想法是:
1 grab 3% of the memory free right now
2 if that caused swap to increase: stop
3 keep the chunk used for 30 seconds by forking off
4 goto 1
Run Code Online (Sandbox Code Playgroud)
——
#!/usr/bin/perl
sub freekb {
my $free = `free|grep buffers/cache`;
my @a=split / +/,$free;
return $a[3];
}
sub swapkb {
my $swap = `free|grep Swap:`;
my @a=split / +/,$swap;
return $a[2];
} …Run Code Online (Sandbox Code Playgroud) 该vmtouch(8)工具允许在内存中锁定一个或多个文件。它具有递归模式,但目录仅用于发现文件,并不会自行锁定。
如何锁定内存中的目录,以便 readdir 始终快速,直到我解锁它?
我在关闭交换时遇到了一个奇怪的问题。服务器有 192 GB 内存,154 GB 可用内存。
它是一个运行多个 Linux KVM 虚拟机的管理程序。
当尝试:
# swapoff -a
swapoff: /dev/sda2: swapoff failed: Cannot allocate memory
Run Code Online (Sandbox Code Playgroud)
但内存是免费的:
# cat /proc/meminfo
MemTotal: 197805748 kB
MemFree: 162274264 kB
MemAvailable: 162388912 kB
Buffers: 432 kB
Cached: 353524 kB
SwapCached: 221828 kB
Active: 28253440 kB
Inactive: 5349056 kB
Active(anon): 28159204 kB
Inactive(anon): 5289320 kB
Active(file): 94236 kB
Inactive(file): 59736 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 124999676 kB
SwapFree: 124534724 kB
Dirty: 796 kB
Writeback: 0 kB
AnonPages: …Run Code Online (Sandbox Code Playgroud) 我正在编写一个模拟器,它依赖于生成(可能)非常大的问题域。由于数据无法放入 RAM,我使用 4 个四内存映射文件来保存它。这是一个在 64 位 Linux 上运行的 64 位应用程序,具有 8GB 的 RAM。
我的应用程序在多个线程中迭代内存映射并对它们执行读写操作。但是我的程序在启动后不久导致 OOM(没有发生颠簸):
[ 683.899682] Purging GPU memory, 25 pages freed, 12838 pages still pinned.
[ 683.899683] 50 and 0 pages still available in the bound and unbound GPU page lists.
[ 683.899732] Purging GPU memory, 0 pages freed, 12838 pages still pinned.
[ 683.899732] 50 and 0 pages still available in the bound and unbound GPU page lists.
[ 683.901441] gnome-shell invoked oom-killer: gfp_mask=0x240c0d0(GFP_TEMPORARY|__GFP_COMP|__GFP_ZERO), order=3, oom_score_adj=0
[ …Run Code Online (Sandbox Code Playgroud) 似乎每个进程都有私有内存映射,既不可读也不可写也不可执行(其标志是“---p”):
grep -- --- /proc/self/maps
7f2bd9bf7000-7f2bd9df6000 ---p 001be000 fc:00 3733 /lib/x86_64-linux-gnu/libc-2.19.so
7f2bd9e04000-7f2bda003000 ---p 00003000 fc:00 3743 /lib/x86_64-linux-gnu/libdl-2.19.so
7f2bda042000-7f2bda241000 ---p 0003d000 fc:00 36067 /lib/x86_64-linux-gnu/libpcre.so.3.13.1
Run Code Online (Sandbox Code Playgroud)
在共享库中返回一些,并为 java (JVM) 进程执行此操作,甚至会返回数十个数百兆字节的匿名映射。
编辑:如果这些映射是占位符,谁将使用这些保留的位置,哪些事件和其他活动受到保护 - 换句话说:如果这些占位符不存在,可能会发生什么错误行为?
第二次编辑:鉴于共享库中的这些漏洞实际上有助于编译器和/或动态链接器的某些目的,因此在 JVM 进程中可见的匿名映射中的这些漏洞必须有其他目的。按大小对 tomcat JVM 进程的匿名映射进行排序:
20 MB 00007FA0AAB52000-00007FA0AC000000 ---p 00000000 00:00 0
41 MB 00007FA0B1603000-00007FA0B4000000 ---p 00000000 00:00 0
50 MB 00007FA090D04000-00007FA094000000 ---p 00000000 00:00 0
53 MB 00007FA0F8A40000-00007FA0FC000000 ---p 00000000 00:00 0
61 MB 00007FA0C42C5000-00007FA0C8000000 ---p 00000000 00:00 0
61 MB 00007FA0CC29A000-00007FA0D0000000 ---p 00000000 00:00 0
61 MB …Run Code Online (Sandbox Code Playgroud) 我想查看内核为我的进程之一管理的分页表。在我的情况下,PID 4680 映射到dhclient. 因此,为了查看页表,我尝试了以下操作:
sudo cat /proc/4680/pagemap
Run Code Online (Sandbox Code Playgroud)
然而,这个命令只是挂在我的 Ubuntu 14.04 上,没有任何输出。我试过等待 2 分钟,然后不得不杀死它。
有没有更好的方法来做到这一点?