İlkel alanlar nerede depolanır?
İlkel alanlar, bir yerde başlatılan nesnenin bir parçası olarak depolanır . Bunun nerede olduğunu düşünmenin en kolay yolu - öbek. Ancak , bu her zaman böyle değildir. Java teorisi ve pratiğinde tanımlandığı gibi : Kentsel performans efsaneleri, tekrar gözden geçirildi :
JVM'ler, kaçış analizi adı verilen bir tekniği kullanabilirler; bu sayede belirli nesnelerin tüm ömürleri boyunca tek bir dişe sınırlı kaldığını ve bu ömrün belirli bir yığın çerçevesinin ömrü ile sınırlandırıldığını söyleyebilirler. Bu tür nesneler yığın yerine istif üzerinde güvenle tahsis edilebilir. Daha da iyisi, küçük nesneler için, JVM tahsisi tamamen ortadan kaldırabilir ve nesnenin alanlarını kayıtlara kaldırabilir.
Bu nedenle, "nesne oluşturulur ve alan da oradadır" derken, öbek üzerinde veya yığında bir şey olup olmadığı söylenemez. Küçük, kısa ömürlü nesneler için, 'nesnenin' bu şekilde bellekte kalmayacağını ve bunun yerine alanlarını doğrudan kayıt defterlerine yerleştirebileceğini unutmayın.
Rapor şununla sona erer:
JVM'ler, yalnızca geliştiricinin bildiğini varsayarsak kullandığımız şeyleri bulmakta şaşırtıcı derecede iyidir. JVM'nin yığın tahsisi ve yığın tahsisi arasında durum bazında seçmesine izin vererek, programcının yığında mı yoksa yığın üzerinde mi dağıtılacağı konusunda agonize etmesine gerek kalmadan yığın tahsisinin performans avantajlarını elde edebiliriz.
Dolayısıyla, şuna benzeyen bir kodunuz varsa:
void foo(int arg) {
Bar qux = new Bar(arg);
...
}
nerede ...
izin vermez qux
o kapsamını bırakmak, qux
olabilir yerine yığın tahsis edilecek. Bu aslında VM için bir kazançtır, çünkü bunun hiç bir zaman çöp toplanması gerekmediği anlamına gelir - kapsamdan çıktığında kaybolacaktır.
Wikipedia'da kaçış analizi hakkında daha fazla bilgi . Gazetelere dalmaya istekli olanlar için , IBM'den Java için Escape Analysis . C # dünyasından gelenler için Yığın Bir Uygulama Ayrıntısı ve Eric Lippert tarafından Değer Türleri Hakkında Gerçeği iyi okumalar bulabilirsiniz (Java kavramlarında çoğu kavram ve özellik aynı veya benzer olduğu için faydalıdır) . Neden .Net kitaplar yığın vs yığın bellek ayırma hakkında konuşurlar? ayrıca buna da giriyor.
Yığın ve yığın yığınında
Öbek üzerinde
Öyleyse, neden yığın ya da öbek yok? Kapsam bırakan şeyler için yığın pahalı olabilir. Kodu düşünün:
void foo(String arg) {
bar(arg);
...
}
void bar(String arg) {
qux(arg);
...
}
void qux(String arg) {
...
}
Parametreler de yığının bir parçasıdır. Bir öbeğiniz olmadığı durumda, yığında tüm değer kümesini geçiyor olmalısınız. Bu "foo"
küçük ve küçük dizeler için gayet iyi ... ama birisi o dizgeye büyük bir XML dosyası koyarsa ne olur. Her arama dev dizenin tamamını yığına kopyalar - ve bu çok israf olur.
Bunun yerine, yaşamı biraz fazla olan nesnelerin hemen kapsamın dışına (başka bir kapsama geçtiniz, başka birinin koruduğu bir yapıya sıkışmış vb.) Dışa yığın adı verilen bir alana koymak daha iyidir.
Yığında
Sen yok gerek yığını. Bir varsayımsal olarak, bir yığın (keyfi derinlikte) kullanmayan bir dil yazabilir. Gençliğimde öğrendiğim eski bir BASIC bunu yaptı, biri yalnızca 8 seviye gosub
çağrı yapabiliyordu ve tüm değişkenler globaldi - yığın yoktu.
Yığının avantajı, bir kapsamla var olan bir değişkeniniz olduğunda, o kapsamdan ayrıldığınızda, o yığın çerçevesinin fırlatılmasıdır. Orada olanı ve olmayanı gerçekten kolaylaştırıyor. Program başka bir işleme, yeni bir yığın çerçeveye geçer; program işleme geri döner ve mevcut kapsamınızı gören programa geri dönersiniz; Program prosedürü terk eder ve istifin üzerindeki tüm öğeler serbest bırakılır.
Bu, kodun bir yığın ve bir yığın kullanması için çalışma zamanını yazan kişinin hayatı kolaylaştırır. Bunlar sadece kod üzerinde çalışarak birçok kişi ve kodu dilde yazan kişinin açık bir şekilde düşünmekten kurtulmasına izin veren birçok yöntem ve yöntemdir.
Yığının doğası da parçalanamayacağı anlamına gelir. Bellek parçalanması öbek ile ilgili gerçek bir sorundur. Birkaç nesne atarsınız, sonra çöpler bir tane toplar ve sonra bir sonraki büyükler için yer bulmayı deneyin. Onun bir karmaşa. Bir şeyleri yığına koyabilmek, bununla uğraşmak zorunda olmadığınız anlamına gelir.
Bir şey çöp toplandığında
Bir şey çöp toplanınca gitmiş demektir. Ancak sadece toplanan çöpler çünkü zaten unutulmuş durumda - programdaki mevcut programdan erişilebilen nesneye daha fazla referans yok.
Bunun, çöp toplama işleminin çok büyük bir sadeleştirme olduğuna dikkat çekeceğim. Çeşitli bayrakları (kullanarak çöp toplamayı çimdik - Orada bile Java içinde birçok çöp toplayıcılar (olan docs ) Bu farklı davranır ve her biri şeyler yapar nasıl nüansları Bu yanıt için biraz çok derin Sen okumak isteyebilirsiniz.. Java Garbage Collection Bazılarının nasıl çalıştığı hakkında daha iyi bir fikir edinmek için temel bilgiler .
Yani, yığına bir şey tahsis edilmişse, bunun bir parçası olarak toplanan çöp değildir System.gc()
- yığın çerçevesi açıldığında serbest bırakılır. Yığında bir şey varsa ve yığında bir şeyden başvuruda bulunulursa, o zaman toplanan çöpler olmaz.
Bu neden önemli?
Çoğunlukla, geleneği. Yazılan kitap ve derleyici sınıfları ve çeşitli bit belgeleri, yığın ve yığında önemli bir yer tutar.
Bununla birlikte, günümüzün sanal makineleri (JVM ve benzeri), bunu programlayıcıdan gizli tutmaya çalışmak için oldukça uzadı. Birinden veya diğerinden bitmediğiniz ve nedenini bilmek zorunda olmadıkça (sadece depolama alanını uygun şekilde artırmak yerine) çok fazla önemli değil.
Nesne, bir yerde ve bulunduğu yerde uygun bir süre boyunca doğru ve hızlı bir şekilde erişilebildiği yerdedir. Yığın ya da yığın üzerinde ise - gerçekten önemli değil.