awk内存泄漏?

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

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

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


如果 awk 版本很重要:

⑆ awk --version
awk version 20070501

这是我根据 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

答案1

这个说法很奇怪:

split("0,2,4,5,7,9,11,12",a,",");

它重复分割常量字符串以创建数组a。如果将其移动到一个BEGIN部分中,程序应该以相同的方式工作 - 无需a为每个输入记录分配数组的新副本。

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

答案2

这是一个不会泄漏的 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) }'

几乎是一样的。$1被替换为$F[0]并被i替换为$i。哈希值a被替换为实际的数组@a

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

相关内容