아 메모리 누수?

아 메모리 누수?

에 따라이것명령을 실행하고 있어요

< /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/awkOSX에서는 매우 빠르게 누출된다는 것을 알 수 있습니다. Apple에 버그 보고 시스템이 있다면 이는 훌륭한 선택이 될 것입니다.

답변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.

일부 입력을 생성하고 출력을 비교하고 차이점을 확인하는 것이 좋습니다. 해석된 언어가 부동 소수점을 처리하는 방법에는 미묘한 차이가 있는 경우가 많습니다.

관련 정보