[unix] 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



답변

이 진술은 이상하다 :

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

상수 문자열을 반복적으로 분할하여 배열을 만듭니다 a. 이 BEGIN섹션을 섹션 으로 이동하면 a각 입력 레코드에 대해 새 어레이 사본을 할당하지 않고 프로그램이 동일하게 작동해야합니다 .

주석 처리 : for-loop와 expression은 단순한 방식으로 메모리를 할당하지 않습니다. mawk, gawk 및 awk를 빠르게 비교하면 처음 두 개에는 문제가 없지만 /usr/bin/awkOSX에서는 빠르게 누출됩니다. Apple에 버그보고 시스템이 있다면 그 곳을 방문하십시오.


답변

누출되지 않는 펄 동등 물은 다음과 같습니다.

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.

약간의 입력을 생성하고 출력을 비교하고 둘 사이의 차이를 기록하는 것이 현명합니다. 해석 언어가 부동 소수점을 처리하는 방법에 대한 뉘앙스가 종종 있습니다.


답변