Linux, bir çatalın ardından bellek kullanımını düşük tutmak için COW kullanır, ancak Perl 5 değişkenlerinin perl
numaralı çalışmasında bu optimizasyonu ortadan kaldırdığı görülmektedir. Örneğin, değişken için:Alt süreçler meta verilere dokunduğunda bellek patlamasını nasıl engelleyebilirim?
my $s = "1";
perl
gerçekten depoluyor:
SV = PVIV(0x100821610) at 0x1008272e8
REFCNT = 1
FLAGS = (IOK,POK,pIOK,pPOK)
IV = 1
PV = 0x100201d50 "1"\0
CUR = 1
LEN = 16
: Sayısal bir bağlamda o dizeyi kullandığınızda
SV = PV(0x100801068) at 0x1008272e8
REFCNT = 1
FLAGS = (POK,pPOK)
PV = 0x100201d50 "1"\0
CUR = 1
LEN = 16
, verileri temsil eden C struct
değiştirir
Dize işaretçisinin kendisi değişmedi (hala 0x100201d50
), ancak şimdi farklı bir C struct
() PV
yerine). Değeri hiç değiştirmedim, ama aniden bir COW maliyeti ödüyorum. Bu zaman tasarrufu (perl
"0"
0
bir ikinci kez dönüştürmek zorunda kalmazsınız böylece bir Perl 5 değişkeninin perl
gösterimini kilitlemek için herhangi bir yolu var) hack benim bellek kullanımı zarar vermez?
perl -MDevel::Peek -e '$s = "1"; Dump $s; $s + 0; Dump $s'
Güzel, ama birkaç yüz MB veri ayırdığınızda, birkaç çocuğu çatalladığınızda ve çocukların bitmesiyle ne olacağını biliyor musunuz? GC yine de seni öldürecek. Bu üzücü bir hikaye ama Perl bu tür bir iş için sadece yanlış bir araçtır.Kısmen END {kill 9 $$} yaklaşımını kullanarak çözdük ancak bu noktada daha iyi bir araç aramalıyız ;-) –
GC beni rahatsız etmiyor, gerçek kod "mod_perl" tabanlı ve her çocuk birçok kez yeniden kullanılıyor . Problem şu ki, ebeveynin içinde yüklenen konfigürasyon verileri, çocukların hiçbir zaman modifiye etmemesine rağmen muhtemelen yüzlerce çocuğun her birine kopyalanıyor (Perl 5'in bakış açısına göre, 'perl' meta verilerle uğraşıyor). Göz önünde bulundurduğum diğer çözüm, yapılandırma verilerini ayrı bir sürece taşımak ve çocukların alan adı soketleriyle konuşmasına izin vermek. –
Daha hızlı olacak paylaşılan belleği de kullanabilirsiniz. –