kebocoran memori awk?

11

Berdasarkan ini saya menjalankan perintah

< /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

Saya perhatikan bahwa memori yang digunakan oleh awk terus bertambah saat perintah ini berjalan, misalnya mengonsumsi lebih dari 500MB memori saat 75MB data audio mentah diputar. Semua perintah lain dalam pipa mempertahankan jumlah memori yang konstan.

Untuk apa awk menggunakan memori ini dan apakah ada alternatif yang melakukan pemrosesan aliran yang dimaksudkan hanya menggunakan jumlah memori yang konstan?


dalam hal versi awk penting:

 awk --version
awk version 20070501

Inilah perintah yang saya uji berdasarkan jawaban 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
bames53
sumber
Saya juga melihat kebocoran memori pada sistem BSD-Darwin (Mac) saya.
Otheus
Anda mengatakan Here's the command I tested...tetapi Anda lupa memberi tahu kami hasil pengujian itu - apakah itu menyelesaikan masalah atau tidak? Mungkin tidak karena setiap referensi ke elemen di a[]dalam loop akan membuat entri jika tidak ada sehingga jika tidak - apakah itu membantu jika Anda secara eksplisit menghapus array sebelum membelah atau setelah menggunakannya, misalnya awk '{ delete a; 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)) }'? Dengan segmen kode itu, Anda harus meninggalkan pemisahan () di lokasi aslinya, bukan memindahkannya ke BEGIN.
Ed Morton

Jawaban:

11

Pernyataan ini aneh:

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

Ini secara berulang membagi string konstan untuk membuat array a. Jika Anda memindahkannya ke BEGINbagian, program harus bekerja sama - tanpa mengalokasikan salinan aarray untuk setiap input-record.

Mengatasi komentar: for-loop dan ekspresi tidak mengalokasikan memori secara sederhana. Perbandingan cepat antara mawk, gawk dan awk menunjukkan bahwa tidak ada masalah dengan dua yang pertama, tetapi /usr/bin/awkpada OSX bocor dengan cepat. Jika Apple memiliki sistem pelaporan bug, itu akan menjadi tempatnya.

Thomas Dickey
sumber
1
Saya melakukan seperti yang Anda sarankan pada Mac saya (saya bukan OP). Saya masih melihat kebocoran memori dengan awk.
Otheus
Entah bagaimana, hanya referensi yang suatu memori hash kegunaan.
Otheus
Sama disini; Saya masih melihat pertumbuhan memori. Saya juga melakukan perbandingan kasar dan penggunaan memori tampaknya tumbuh pada tingkat yang sama dengan perubahan ini.
bames53
Bahkan ini akan menyebabkan kebocoran memori:awk 'BEGIN { split("0,2,4,5,7,9,11,12",a,","); } { for (i = 0; i < 1; i+= 0.0001) a[1]; }'
Otheus
Anda bisa beralih ke mawk atau gawk. Sistem dasar Apple mencakup beberapa barang antik asli.
Thomas Dickey
5

Berikut ini setara dengan perl yang tidak bocor:

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) }'

Hampir identik. $1digantikan oleh $F[0]dan idiganti dengan $i. Hash adiganti dengan array aktual @a,.

Anda sebaiknya menghasilkan beberapa input dan membandingkan perbedaan keluaran dan catatan di antara keduanya. Seringkali ada nuansa bagaimana bahasa interpretatif menangani floating point.

Otheus
sumber