fuite de mémoire awk?


11

Sur cette base, j'exécute la commande

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

Je remarque que la mémoire utilisée par awk augmente continuellement pendant l'exécution de cette commande, par exemple en consommant plus de 500 Mo de mémoire au moment où 75 Mo de données audio brutes ont été lues. Toutes les autres commandes du pipeline conservent une quantité de mémoire constante.

À quoi sert awk cette mémoire et existe-t-il une alternative qui fait le traitement de flux prévu en utilisant uniquement une quantité constante de mémoire?


au cas où la version awk compte:

 awk --version
awk version 20070501

Voici la commande que j'ai testée sur la base de la réponse de 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

Je constate également une fuite de mémoire sur mon système BSD-Darwin (Mac).
Otheus

Vous avez dit Here's the command I tested...mais vous avez oublié de nous dire le résultat de ces tests - cela a-t-il résolu le problème ou non? Ce n'est peut-être pas le cas, car chaque référence à un élément dans a[]la boucle créerait des entrées si elles n'existaient pas, si ce n'est pas le cas - cela aide-t-il si vous supprimez explicitement le tableau avant de le fractionner ou après l'avoir utilisé, par exemple 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)) }'? Avec ce segment de code, vous devez laisser le split () à son emplacement d'origine, pas le déplacer vers BEGIN.
Ed Morton

Réponses:


11

Cette déclaration est étrange:

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

Il fractionne de manière répétitive une chaîne constante pour créer un tableau a. Si vous déplacez cela dans une BEGINsection, le programme devrait fonctionner de la même manière - sans allouer une nouvelle copie du atableau pour chaque enregistrement d'entrée.

Adressage des commentaires: la boucle for et l'expression n'allouent pas la mémoire de manière simple. Une comparaison rapide de mawk, gawk et awk montre qu'il n'y a pas de problème avec les deux premiers, mais /usr/bin/awksur OSX fuit rapidement. Si Apple avait un système de rapport de bogues, ce serait l'endroit où aller.


1
J'ai fait comme vous l'avez suggéré sur mon Mac (je ne suis pas l'OP). Je vois toujours une fuite de mémoire avec awk.
Otheus

D'une certaine façon, il suffit de référencer l' un hachage utilise la mémoire.
Otheus

Pareil ici; Je vois toujours la croissance de la mémoire. J'ai également fait une comparaison approximative et l'utilisation de la mémoire semble augmenter au même rythme avec ce changement.
bames53

Même cela entraînera une fuite de mémoire:awk 'BEGIN { split("0,2,4,5,7,9,11,12",a,","); } { for (i = 0; i < 1; i+= 0.0001) a[1]; }'
Otheus

Vous pouvez passer à mawk ou gawk. Le système de base d'Apple comprend de véritables antiquités.
Thomas Dickey

5

Voici un équivalent perl qui ne fuit pas:

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

C'est presque identique. $1est remplacé par $F[0]et iest remplacé par $i. Le hachage aest remplacé par un tableau réel, @a.

Il serait sage de générer une entrée et de comparer la sortie et de noter les différences entre les deux. Il existe souvent des nuances quant à la manière dont les langages d'interprétation traitent la virgule flottante.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.