awk memory รั่ว?


11

ฐานบนนี้ผมใช้คำสั่ง

< /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 ใช้เพิ่มขึ้นอย่างต่อเนื่องในขณะที่คำสั่งนี้กำลังทำงานตัวอย่างเช่นการใช้หน่วยความจำเกิน 500MB ภายในเวลาที่เล่นข้อมูลเสียงดิบ 75MB คำสั่งอื่น ๆ ทั้งหมดในไปป์ไลน์รักษาจำนวนหน่วยความจำให้คงที่

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

ฉันเห็นหน่วยความจำรั่วในระบบ BSD-Darwin (Mac) ของฉัน
Otheus

คุณพูดHere's the command I tested...แต่คุณลืมที่จะบอกเราถึงผลลัพธ์ของการทดสอบ - มันแก้ปัญหาได้หรือไม่? อาจไม่ได้เนื่องจากทุกการอ้างอิงถึงองค์ประกอบในa[]ลูปจะสร้างรายการหากไม่มีอยู่ดังนั้นหากไม่มี - จะช่วยได้ไหมถ้าคุณลบอาเรย์อย่างชัดเจนก่อนที่จะแยกหรือหลังการใช้งานเช่น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)) }'? ด้วยเซ็กเมนต์รหัสนั้นคุณต้องปล่อยให้แยก () ในตำแหน่งเดิมไม่ย้ายไปยัง BEGIN
Ed Morton

คำตอบ:


11

คำสั่งนี้แปลก:

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

aมันซ้ำแยกสตริงอย่างต่อเนื่องเพื่อสร้างอาร์เรย์ หากคุณย้ายสิ่งนั้นไปยังBEGINส่วนโปรแกรมควรทำงานเหมือนเดิมโดยไม่ต้องจัดสรรสำเนาใหม่ของaอาร์เรย์สำหรับแต่ละอินพุตเรคคอร์ด

การใส่ความเห็น: for-loop และ expression ไม่ได้จัดสรรหน่วยความจำอย่างเรียบง่าย การเปรียบเทียบอย่างรวดเร็วของ mawk, gawk และ awk แสดงให้เห็นว่าไม่มีปัญหากับสองรายการแรก แต่/usr/bin/awkใน OSX จะรั่วไหลอย่างรวดเร็ว หาก Apple มีระบบการรายงานข้อผิดพลาดมันจะเป็นที่ที่ควรไป


1
ฉันทำตามที่คุณแนะนำบน Mac ของฉัน (ฉันไม่ใช่ OP) ฉันยังคงเห็นหน่วยความจำรั่วด้วย awk
Otheus

อย่างใดเพียงแค่อ้างอิงหน่วยความจำที่ใช้กัญชา
Otheus

กันที่นี่; ฉันยังคงเห็นการเติบโตของหน่วยความจำ ฉันทำการเปรียบเทียบคร่าวๆและการใช้หน่วยความจำดูเหมือนว่าจะเพิ่มขึ้นในอัตราเดียวกันกับการเปลี่ยนแปลงนี้
bames53

แม้แต่สิ่งนี้จะทำให้หน่วยความจำรั่ว:awk 'BEGIN { split("0,2,4,5,7,9,11,12",a,","); } { for (i = 0; i < 1; i+= 0.0001) a[1]; }'
Otheus

คุณสามารถเปลี่ยนเป็นเหยี่ยวหรือเหยี่ยว ระบบพื้นฐานของ Apple รวมถึงของโบราณบางอย่าง
Thomas Dickey

5

นี่เทียบเท่า 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.

คุณควรสร้างอินพุตและเปรียบเทียบผลลัพธ์และความแตกต่างระหว่างทั้งสอง มักจะมีความแตกต่างในการตีความภาษาที่จัดการกับจุดลอยตัว

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.