rò rỉ bộ nhớ awk?


11

Dựa vào điều này tôi đang chạy lệnh

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

Tôi nhận thấy rằng bộ nhớ được sử dụng bởi awk liên tục phát triển trong khi lệnh này đang chạy, ví dụ như tiêu thụ hơn 500 MB bộ nhớ vào thời điểm 75 MB dữ liệu âm thanh thô đã được phát. Tất cả các lệnh khác trong đường ống duy trì một lượng bộ nhớ không đổi.

Awk sử dụng bộ nhớ này để làm gì và có một giải pháp thay thế nào xử lý luồng dự định chỉ sử dụng một lượng bộ nhớ không đổi?


trong trường hợp phiên bản awk có vấn đề:

 awk --version
awk version 20070501

Đây là lệnh tôi đã kiểm tra dựa trên câu trả lời của 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

Tôi cũng thấy rò rỉ bộ nhớ trên hệ thống BSD-Darwin (Mac) của mình.
Otheus

Bạn nói Here's the command I tested...nhưng bạn đã quên cho chúng tôi biết kết quả của thử nghiệm đó - nó có giải quyết được vấn đề hay không? Có thể vì mọi tham chiếu đến một phần tử trong a[]vòng lặp sẽ tạo ra các mục nếu chúng không tồn tại nên nếu nó không - có giúp ích gì không nếu bạn xóa rõ ràng mảng trước khi tách hoặc sau khi sử dụng, ví dụ 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)) }'? Với đoạn mã đó, bạn cần để dấu tách () ở vị trí ban đầu, không di chuyển nó sang BEGIN.
Ed Morton

Câu trả lời:


11

Tuyên bố này là kỳ lạ:

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

Nó lặp đi lặp lại tách một chuỗi không đổi để tạo ra một mảng a. Nếu bạn di chuyển phần đó vào một BEGINphần, chương trình sẽ hoạt động như nhau - mà không phân bổ một bản sao mới của amảng cho mỗi bản ghi đầu vào.

Nhận xét địa chỉ: vòng lặp for và biểu thức không phân bổ bộ nhớ một cách đơn giản. So sánh nhanh về mawk, gawk và awk cho thấy không có vấn đề gì với hai cái đầu tiên, nhưng /usr/bin/awktrên OSX không bị rò rỉ nhanh chóng. Nếu Apple có một hệ thống báo cáo lỗi, đó sẽ là nơi cần đến.


1
Tôi đã làm như bạn đề xuất trên máy Mac của tôi (Tôi không phải là OP). Tôi vẫn thấy rò rỉ bộ nhớ với awk.
Otheus

Bằng cách nào đó, bạn chỉ cần tham khảo các một bộ nhớ băm sử dụng.
Otheus

Tương tự ở đây; Tôi vẫn thấy sự tăng trưởng bộ nhớ. Tôi cũng đã làm một so sánh sơ bộ và việc sử dụng bộ nhớ dường như đang tăng với tốc độ tương tự với sự thay đổi này.
bames53

Thậm chí, điều này sẽ gây rò rỉ bộ nhớ:awk 'BEGIN { split("0,2,4,5,7,9,11,12",a,","); } { for (i = 0; i < 1; i+= 0.0001) a[1]; }'
Otheus

Bạn có thể chuyển sang mawk hoặc gawk. Hệ thống cơ sở của Apple bao gồm một số đồ cổ thực sự.
Thomas Dickey

5

Đây là một tương đương perl không rò rỉ:

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

Nó gần như giống hệt nhau. $1được thay thế bởi $F[0]iđược thay thế bằng $i. Hàm băm ađược thay thế bằng một mảng thực tế , @a.

Bạn sẽ là khôn ngoan để tạo ra một số đầu vào và so sánh sự khác biệt đầu ra và lưu ý giữa hai. Thường có nhiều sắc thái về cách các ngôn ngữ diễn giải đối phó với dấu phẩy động.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.