"less" 为 gzip 文件的管道输出消耗大量 RAM,为什么?
"less" consumes lots of RAM for a piped output on gzipped file, why?
对不起,cat
和 echo
前期无用,但是当 运行 less
在 ~2GB .gz 文件上时,我看到了 ~25GB 的 RAM消费(尽管输出被输送到 awk 并在那里消费):
[user@mybox:~]$ cat <(echo '173abcde7665559.90651926
131abcde7298936.49040546
... (25 lines total here) ...
186abcde4858463.43044639
163abcde9409643.80726489'|awk '{print "KEY 1"length()-16":"}';
less /tmp/stats.gz)|awk '{if("KEY"==){K[]=1}else{if( in K)print}}' >bad25&
我预计上面的内容不需要 RAM 就可以完成,但令我惊讶的是它在 ~2.5 小时后的样子(到 89.8% 读取 .gz 时):
[user@mybox:~]$ ps auxf|grep -e 'pts/2' -e PID |grep -v grep
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
user 26896 0.0 0.0 68356 1580 pts/2 Ss+ 15:23 0:00 \_ /bin/bash
user 27927 0.7 0.0 58932 476 pts/2 S 15:23 1:00 \_ cat /dev/fd/63
user 27929 0.0 0.0 68356 716 pts/2 S+ 15:23 0:00 | \_ /bin/bash
user 27932 99.9 75.0 22389852 18512388 pts/2 R+ 15:23 137:42 | \_ less /tmp/stats.gz
user 27933 0.0 0.0 65928 1168 pts/2 S+ 15:23 0:00 | \_ /bin/sh - /usr/bin/lesspipe.sh /tmp/stats.gz
user 27934 1.3 0.0 4176 492 pts/2 S+ 15:23 1:52 | \_ gzip -dc -- /tmp/stats.gz
user 27928 2.1 0.0 63908 776 pts/2 S 15:23 2:56 \_ awk {if("KEY"==){K[]=1}else{if( in K)print}}
[user@mybox:~]$ free -m
total used free shared buffers cached
Mem: 24103 23985 117 0 125 3958
-/+ buffers/cache: 19901 4201
Swap: 8191 7914 277
[user@mybox:~]$ echo 1|awk "{print `cat /proc/27934/fdinfo/3|sed -n 's/pos:[ \t]*//p'`/`du -b /tmp/stats.gz|sed 's/[ \t].*//'`}";date
0.898284
Sat Apr 4 17:41:24 GMT 2015
我会尝试一些其他选项(比如用直接 gzip -dc
或 zcat
重写我的命令)看看这些是否有帮助,但如果有人可以告诉为什么会发生这种情况less (或任何其他命令),无论是已知的 less
还是 bash
错误已在更高版本中修复?也许一些 shell 技巧可以强制 less 正常运行?
P.S。 stats.gz 是未压缩的 25261745373 字节(环绕 MAX_INT 5 次):
[user@mybox:~]$ ls -l /tmp/stats.gz
-rw-r--r-- 1 user users 1837966346 Apr 3 21:42 /tmp/stats.gz
[user@mybox:~]$ gzip -l /tmp/stats.gz
compressed uncompressed ratio uncompressed_name
1837966346 3786908893 51.5% /tmp/stats
less
将所有数据存储在内存中。这就是允许您向上滚动的原因。
对不起,cat
和 echo
前期无用,但是当 运行 less
在 ~2GB .gz 文件上时,我看到了 ~25GB 的 RAM消费(尽管输出被输送到 awk 并在那里消费):
[user@mybox:~]$ cat <(echo '173abcde7665559.90651926
131abcde7298936.49040546
... (25 lines total here) ...
186abcde4858463.43044639
163abcde9409643.80726489'|awk '{print "KEY 1"length()-16":"}';
less /tmp/stats.gz)|awk '{if("KEY"==){K[]=1}else{if( in K)print}}' >bad25&
我预计上面的内容不需要 RAM 就可以完成,但令我惊讶的是它在 ~2.5 小时后的样子(到 89.8% 读取 .gz 时):
[user@mybox:~]$ ps auxf|grep -e 'pts/2' -e PID |grep -v grep
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
user 26896 0.0 0.0 68356 1580 pts/2 Ss+ 15:23 0:00 \_ /bin/bash
user 27927 0.7 0.0 58932 476 pts/2 S 15:23 1:00 \_ cat /dev/fd/63
user 27929 0.0 0.0 68356 716 pts/2 S+ 15:23 0:00 | \_ /bin/bash
user 27932 99.9 75.0 22389852 18512388 pts/2 R+ 15:23 137:42 | \_ less /tmp/stats.gz
user 27933 0.0 0.0 65928 1168 pts/2 S+ 15:23 0:00 | \_ /bin/sh - /usr/bin/lesspipe.sh /tmp/stats.gz
user 27934 1.3 0.0 4176 492 pts/2 S+ 15:23 1:52 | \_ gzip -dc -- /tmp/stats.gz
user 27928 2.1 0.0 63908 776 pts/2 S 15:23 2:56 \_ awk {if("KEY"==){K[]=1}else{if( in K)print}}
[user@mybox:~]$ free -m
total used free shared buffers cached
Mem: 24103 23985 117 0 125 3958
-/+ buffers/cache: 19901 4201
Swap: 8191 7914 277
[user@mybox:~]$ echo 1|awk "{print `cat /proc/27934/fdinfo/3|sed -n 's/pos:[ \t]*//p'`/`du -b /tmp/stats.gz|sed 's/[ \t].*//'`}";date
0.898284
Sat Apr 4 17:41:24 GMT 2015
我会尝试一些其他选项(比如用直接 gzip -dc
或 zcat
重写我的命令)看看这些是否有帮助,但如果有人可以告诉为什么会发生这种情况less (或任何其他命令),无论是已知的 less
还是 bash
错误已在更高版本中修复?也许一些 shell 技巧可以强制 less 正常运行?
P.S。 stats.gz 是未压缩的 25261745373 字节(环绕 MAX_INT 5 次):
[user@mybox:~]$ ls -l /tmp/stats.gz
-rw-r--r-- 1 user users 1837966346 Apr 3 21:42 /tmp/stats.gz
[user@mybox:~]$ gzip -l /tmp/stats.gz
compressed uncompressed ratio uncompressed_name
1837966346 3786908893 51.5% /tmp/stats
less
将所有数据存储在内存中。这就是允许您向上滚动的原因。