awk 内存泄漏?

bam*_*s53 11 osx memory awk

基于此,我正在运行命令

< /dev/urandom hexdump -v -e '/1 "%u\n"' |
awk '{ split("0,2,4,5,7,9,11,12",a,",");
       for (i = 0; i < 1; i+= 0.0001)
         printf("%08X\n", 100*sin(1382*exp((a[$1 % 8]/12)*log(2))*i)) }' |
xxd -r -p |
sox -traw -r44100 -b16 -e unsigned-integer - -tcoreaudio
Run Code Online (Sandbox Code Playgroud)

我注意到 awk 使用的内存在此命令运行时不断增长,例如在播放 75MB 的原始音频数据时消耗了超过 500MB 的内存。管道中的所有其他命令都保持恒定的内存量。

awk 使用此内存的目的是什么,是否有替代方案可以仅使用恒定数量的内存进行预期的流处理?


如果 awk 版本很重要:

? awk --version
awk version 20070501
Run Code Online (Sandbox Code Playgroud)

这是我根据 Thomas Dickey 的回答测试的命令:

< /dev/urandom hexdump -v -e '/1 "%u\n"' |
awk 'BEGIN { split("0,2,4,5,7,9,11,12",a,",") }
           { for (i = 0; i < 1; i+= 0.0001)
               printf("%08X\n", 100*sin(1382*exp((a[$1 % 8]/12)*log(2))*i)) }' |
xxd -r -p |
sox -traw -r44100 -b16 -e unsigned-integer - -tcoreaudio
Run Code Online (Sandbox Code Playgroud)

Tho*_*key 11

这个说法很奇怪:

split("0,2,4,5,7,9,11,12",a,",");
Run Code Online (Sandbox Code Playgroud)

它反复拆分一个常量字符串来创建一个数组a。如果你把它移到一个BEGIN节中,程序应该工作相同——不需要a为每个输入记录分配一个新的数组副本。

寻址注释:for 循环和表达式不会以简单的方式分配内存。快速比较 mawk、gawk 和 awk 表明前两者没有问题,但/usr/bin/awk在 OSX 上确实泄漏很快。如果 Apple 有一个错误报告系统,那将是你要去的地方。


Oth*_*eus 5

这是一个不会泄漏的 perl 等效项:

perl -lne 'BEGIN { @a=(0,2,4,5,7,9,11,12);}
   for ($i = 0; $i < 1; $i+= 0.0001) {
     printf("%08X\n", 100*sin(1382*exp($a[$F[0] % 8]/12)*log(2))*$i) }'
Run Code Online (Sandbox Code Playgroud)

这几乎是相同的。$1被替换$F[0]i替换$i。散列a被替换为实际数组,@a

您最好生成一些输入并比较输出并注意两者之间的差异。关于解释性语言如何处理浮点数,通常存在细微差别。