ProgramlamaSistem Perl Geliştirici

Perl'de iç dil bellek otomatik ölçekleme (otomatik bellek yönetimi) kullanmanın avantajları ve dezavantajları nelerdir? Büyük veri setleri ve döngüsel referanslarla işleme sırasında hangi tuzaklar vardır?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap.

Perl, bellek yönetimini otomatik olarak gerçekleştirir: Değişkenler, onlara referans kalmadığında yok edilir (referans sayımı). Perl'deki çöp toplayıcı, tipik bir izleme GC kullanmaz ve referans sayısına dayanır.

Avantajlar:

  • Programlama daha kolaydır — çoğu nesne otomatik olarak serbest bırakılır.
  • Belleği elle serbest bırakma gereksinimi yoktur (örneğin, C'deki gibi free() ile).

Dezavantajlar ve tuzaklar:

  • Perl döngüsel referansları tespit etmez: İki veya daha fazla değişken birbiriyle referans ediliyorsa, bellek otomatik olarak serbest bırakılmaz.
  • Büyük geçici veri yapıları (büyük diziler, hash'ler vb.) ile çalışırken — referanslar saklandığında bellek anında serbest bırakılmaz ve "sızıntı" meydana gelebilir.
  • Kapalı bağlantılar, örneğin, kapanışlar ve anonim fonksiyonlar, “ömür boyu” nesnelere (bellek sızıntısı) yol açabilir.

Döngü referansı örneği:

my $a = {}; my $b = {}; $a->{b} = $b; $b->{a} = $a; # Her iki değişken de temizleme sırasında serbest bırakılmaz, perl bunları kaldırmaz

Bu tür sorunları çözmek için Scalar::Util::weaken modülü kullanılır; bu, referansı "zayıflatmayı" sağlar:

use Scalar::Util 'weaken'; my $a = {}; my $b = {}; $a->{b} = $b; weaken($b->{a} = $a);

Tuzaklı soru.

Perl üzerindeki tüm açık değişkenler silindiğinde, içlerinde referanslar olsa bile herhangi bir nesne ortadan kaldırılır mı?

Cevap: Hayır! Eğer nesneler birbirine referans veriyorsa (döngü oluşturuyorlarsa), Perl bunları silmez — döngüyü manuel olarak kırmak veya Scalar::Util::weaken aracılığıyla bağı zayıflatmak gerekecektir.


Konunun inceliklerini bilmemekten kaynaklanan gerçek hatalardan örnekler.


Hikaye

Büyük sayıda bağlantıyla çalışan uzun süreli bir demon geliştirirken, programcılar IoHandle nesnesi ile bağlı olay işleyicisi arasında döngüsel bir referansı fark etmemişlerdi. Birkaç saat çalıştıktan sonra bellek üssel olarak büyümüştü — sadece Devel::Leak ile yapılan analiz sorunu ortaya çıkardı.


Hikaye

Büyük dosyaların ETL sürecinde, milyonlarca geçici hash öğesi birikmesi, döngü tamamlandıktan sonra bile sürecin "donmasına" neden oluyordu. Bu, bir öğenin üst düzeydeki referansına yönelik yerleşik bir referansı saklıyor olmasından kaynaklanıyordu (üç seviyeli bağlantılar için) ve bellek serbest bırakılmıyordu. Şemanın kısmi yeniden yapılandırması sızıntıyı önlemeye yardımcı oldu.


Hikaye

Programcılar MapReduce motorunda, bağlamın kopyalarını anonim alt programlarda saklayarak kapalama kullandılar. Bu alt programlar “sızdı” — bellek, batch görevlerinin sonlanmasından sonra bile serbest bırakılmadı, çünkü bağlam, kendilerine referanslar içeriyordu. Doğru imha için açık bir undef eklendi.