2008-10-03 12 views
5

Büyük bir skalaya karşı düzenli bir ifade çalıştırıyorum.Perl regex'im neden bu kadar çok bellek kullanıyor?

# A 
if (${$c} =~ m/\G<<\s*/cgs) 
{ 
    #B 
    ... 
} 

$c oldukça büyük bir skalar (21M civarında) bir referans, ama pos(${$c}) sağ doğruladık: Bu maç şey yakalama değil de, benim süreci bu maçtan sonra 30M tarafından yetişir Yer ve ifade ilk karakterde eşleşir, pos(${$c}) eşleşmeden sonra doğru yere güncellenir. Ancak bahsettiğim gibi, bu maçla hiçbir şey yakalamamış olmama rağmen, süreç #A ve #B arasında yaklaşık 30 milyon kişi büyüdü. Hafızam nereye gidiyor?

Düzeltme: Evet, $& kullanımı suçlandı. Perl 5.8.8 kullanıyoruz ve betiğimde Getopt::Declare kullanıyorduk, bu da dahili Text::Balanced kullanıyor. Bu modülün 1.95 sürümü $& kullanıyordu. Perl 5.10 ile birlikte gelen 2.0.0 sürümü, referansı $&'a kaldırdı ve sorunu hafifletiyor.

cevap

20

Sadece hızlı bir akıl sağlığı kontrolü, kodunuzda herhangi bir yerde &, $ `veya $ '(bazen $ MATCH, $ PREMATCH ve $ POSTMATCH denir) bahsediyor musunuz? Eğer öyleyse, bu değişkenleri incelemek isterseniz, Perl tüm dizginizi her düzenli ifade eşleşmesi için kopyalar.

"Kodunuzda", bu durumda, dolaylı olarak, bu değişkenlere başvuran modülleri kullanma da dahil olmak üzere use English'u use English qw(-no_match_vars) yerine yazmak anlamına gelir. Eğer emin değilseniz

, sen kullanıldıkları yerlerde anlamaya kullanıldıkları edilip edilmediğini belirlemek için Devel::SawAmpersand modülü kullanmak ve Devel::FindAmpersand olabilir.

Bellekteki artış için başka nedenler de olabilir (hangi Perl sürümünü kullanıyorsunuz?), Ancak eşleşme değişkenleri, kullanıldıklarında belleğinizi kesinlikle esecek ve dolayısıyla büyük olasılıkla bir suçlu olacaktır. işte bu gibi

Görüşürüz

Paul

+0

Kesinlikle görünüyor. FindAmpersand'ı perlimde çalıştıramıyorum çünkü iş parçacığı etkinleştirildi, bu yüzden sadece bu testi çalıştırmak için perl'i derledim, ancak SawAmpersand evet bildiriyor. –

+0

grep veya ack, kodunuzda herhangi bir yerde bulunup bulunmadıklarını da söyleyebilmelidir. –

+0

Bunu denedim ve kodumda hiçbir şey bulamadı, bu yüzden nihayet @INC'deki tüm kütüphanelerin içine girmeye başladı ve nihayet $ &. Bu kütüphaneden kurtulmak, bellek kullanım problemlerimi düzeltmek için uzun bir yol kat etti. –