我们有一个相当复杂的 PHP 脚本,它会产生许多大小页面错误。
$> ps -o min_flt,maj_flt,time,cmd,pid 4686
MINFL MAJFL TIME CMD PID
3074640 255514 00:06:51 php scripts/daemon/PostProc 4686
此脚本运行 10 分钟,然后自行终止。Cron 一分钟后重新启动它。
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
4686 apache 20 0 2138m 1.6g 2012 T 48.5 86.9 6:33.30 php
我不知道是什么导致了如此多的页面错误。我怀疑你也不知道。但我希望有人能告诉我一些 Linux 命令,我可以用它们来调查可能导致这些页面错误的原因。
谢谢!
编辑1
我对脚本运行了 strace,以下是我得到的返回结果。
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
20.15 9.297617 22 424130 gettimeofday
13.49 6.223247 64 96600 read
13.01 6.001955 158 37945 stat
8.40 3.876297 306 12677 open
7.43 3.425291 63 54691 write
6.47 2.985425 41 72945 sendto
6.00 2.765838 25 109401 recvmsg
4.84 2.234694 26 85617 close
4.79 2.210381 20 109401 fcntl
3.54 1.635305 22 72934 socket
3.01 1.387212 19 72906 poll
1.96 0.901874 25 35712 70 lstat
1.72 0.795357 22 36467 connect
1.62 0.745462 20 36467 getsockname
1.60 0.740286 20 36467 bind
0.77 0.353189 28 12719 fstat
0.67 0.309640 24 12664 lseek
0.51 0.236759 71 3346 brk
0.01 0.004424 36 123 munmap
0.00 0.000524 25 21 mmap
0.00 0.000000 0 2 mremap
0.00 0.000000 0 11 recvfrom
0.00 0.000000 0 1 shutdown
0.00 0.000000 0 4 uname
0.00 0.000000 0 1 flock
0.00 0.000000 0 1 unlink
------ ----------- ----------- --------- --------- ----------------
100.00 46.130777 1323253 70 total
答案1
当正在运行的程序尝试访问不在 RAM 中的内存时,就会发生页面错误,很可能是在磁盘上的交换文件中。(强制性维基百科文章)
正在运行的命令的输出显示 PHP 程序正在尝试分配 2138MB(“VIRT”列)并且只能在 RAM 中保留 1.6GB(“RES”列)。(引文)
每次脚本访问不在 RAM 中的内容时,就会生成一个页面错误,告诉操作系统需要从磁盘中换入更多的进程内存。
回到你的问题:
但我希望有人可以给我指出一些 Linux 命令,以便我可以调查可能导致这些页面错误的原因。
你可能想看看简单的PHP 程序就是这样。它可能是一个变量,其中的数据被追加到变量中,而不是被删除和覆盖,也可能是您需要限制一次处理的数据集的大小。
如果您需要更多帮助,您可能需要将此问题提交给 PHP 特定论坛。
答案2
如您所见,apache 进程使用了 86% 的内存:
- 脚本存在错误,并且由于设计不良而占用过多内存,
- 或者你应该考虑一些硬件升级(添加内存)。
如果内存使用量没有随着时间的推移而增加,则添加内存可以解决问题。