ProgramlamaBackend Perl Geliştirici

Perl'de karmaşık veri yapıları (dizi içinde hash ve tersi) için bellek yönetimi nasıl gerçekleştirilir ve bu tür yapılarla çalışırken dikkat edilmesi gereken incelikler nelerdir?

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

Cevap

Perl, referans sayımı (reference counting) aracılığıyla otomatik bellek yönetimi kullanır. İç içe yapılandırmalar (örneğin, hash içinde diziler) oluşturduğunuzda, her bir öğe, belirli bir nesneye olan referans sayısını artırır veya azaltır. Referans sayısı sıfıra düştüğünde, bellek otomatik olarak serbest bırakılır.

Sıklıkla döngüsel referanslara dikkat edilmesi gerekir; Perl bunları kendi başına serbest bırakamaz — bu, iç içe yapılarla çalışmanın klasik bir tuzağıdır. Perl ayrıca döngüleri kırmaya izin veren zayıf referansları destekler; Scalar::Util modülü kullanarak zayıf referanslar oluşturabilirsiniz: zayıf bir referans referans sayısını artırmaz.

Örnek — dizi hash'i:

my %hash_of_arrays; $hash_of_arrays{"nums"} = [1,2,3]; $hash_of_arrays{"words"} = ["apple", "banana"];

Örnek — döngüsel referans oluşturma:

my $a = {}; my $b = { next => $a }; $a->{next} = $b; # Burada bir döngü oluşur dump($a); # Yapıyı görüntülemek için Data::Dumper'ı kullanın

Bellek sızıntılarını önlemek için zayıf referanslar kullanılır:

use Scalar::Util qw(weaken); $a->{next} = $b; weaken($a->{next}); # Artık $a->{next} — zayıf bir referans

Kandırıcı soru

Eğer Perl'de döngüsel ilişkiler içeren dış değişkenleri sadece silersek, bellekle ne olur?

Doğru cevap: Hiçbir nesnedeki referans sayısı sıfırlanmaz, çünkü her biri diğerine referans verecektir; bellek serbest bırakılmaz — bellek sızıntısı meydana gelir! Döngüleri manuel olarak kırmak gerekir (örneğin, zayıf referanslar aracılığıyla).

Kod örneği:

my $arr = []; my $h = { arr => $arr }; push @$arr, $h; # Artık $arr ve $h bir döngü oluşturuyor. After undef $arr; undef $h; bellek serbest bırakılmaz.

Tarihçe

Büyük bir Perl projesinde, nesne grafiğini (düğümleri ve ilişkileri) yöneten düğümler, hash'ler ve diziler içindeki referanslarla birbirine bağlıydı. İşlem tamamlandıktan sonra bazı bellek alanları serbest bırakılmadı ve bu yalnızca çok sayıda oturum modunda çalışırken ortaya çıktı. Sorun ancak kod denetimi ve Devel::Cycle kullanarak, Perl bellek yöneticisi tarafından temizlenmeyen referans döngülerinin gözlemlenmesiyle bulundu.

Tarihçe

Kullanıcı için karmaşık veri yapısını (hash içindeki diziler — kullanıcı panelleri) periyodik olarak yeniden yapılandıran bir hizmet yazarken, nesneler arasındaki referansların sıfırlanması üzerinde çalışılmamıştı. Yapılar her veri güncellemesiyle birikmeye devam etti ve hizmet, bellek limitlerini aşan miktarlarda bellek tüketmeye başladı.

Tarihçe

CGI uygulaması içinde önbellekleme gerçekleştirilirken, karmaşık ilişkili yapılar (diziler ve hash'ler) kullanmaya karar verildi. Eski değerlerin yanlış bir şekilde sıfırlanmasından dolayı dizinin bir elemanı, yapının tamamına referans vermeye devam etti ve HTTP istekleri arasında bellek serbest bırakılmadı, bu da Apache sürecinin bellek kullanımının artmasına neden oldu.