Java'da statik yöntemler ve statik değişkenler nerede depolanır?


116

Örneğin:

class A {
    static int i=0;
    static int j;

   static void method() {
       // static k=0; can't use static for local variables only final is permitted
       // static int L;
    }
}

Bu değişkenler Java'da, yığın içinde veya yığın belleğinde nerede depolanacak? Nasıl saklanır?


2
Oracle'ın Resmi web sitesinde Çöp toplamayı anlamak için çok kullanışlı bir bağlantı: oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/…
Arnav Joshi

Yanıtlar:


144

Statik yöntemler (aslında tüm yöntemler) ve statik değişkenler PermGen, yansıma verilerinin bir parçası oldukları için (sınıfla ilgili veriler, örnekle ilgili değil) öbek bölümünde depolanır .

Açıklama için güncelleme :

PermGen alanında sadece değişkenlerin ve teknik değerlerinin (ilkeller veya referanslar) saklandığını unutmayın.

Statik değişkeniniz, nesnenin kendisi yığının normal bölümlerinde (genç / eski nesil veya hayatta kalan alan) depolanan bir nesneye bir referanstır. Bu nesneler (bunlar vb sınıfları gibi iç nesneler sürece) vardır olup PermGen alanda depolanan.

Misal:

static int i = 1; //the value 1 is stored in the PermGen section
static Object o = new SomeObject(); //the reference(pointer/memory address) is stored in the PermGen section, the object itself is not.


Çöp toplama üzerine bir kelime:

Do not güvenmek finalize()onu çalıştırmak için garantili değil olarak. Bir nesne çöp toplama için uygun olsa bile, çöp toplayıcının ne zaman çalıştırılacağına ve neyin toplanacağına karar vermek tamamen JVM'ye bağlıdır.

Elbette, statik bir değişkeni null olarak ayarlayabilir ve böylece öbek üzerindeki nesnenin başvurusunu kaldırabilirsiniz, ancak bu, çöp toplayıcının onu toplayacağı anlamına gelmez (daha fazla başvuru olmasa bile).

Ek finalize()olarak yalnızca bir kez çalıştırılır, bu nedenle istisnalar atmadığından veya nesnenin toplanmasını engellemediğinden emin olmalısınız. Sonlandırmayı bir istisna yoluyla durdurursanız finalize(), aynı nesnede ikinci kez çağrılmaz.

Son bir not : kodun, çalışma zamanı verilerinin vb. Nasıl saklandığı, kullanılan JVM'ye bağlıdır, yani HotSpot bunu JRockit'ten farklı şekilde yapabilir ve bu aynı JVM'nin sürümleri arasında bile farklılık gösterebilir. Yukarıdakiler Java 5 ve 6 için HotSpot'a dayanmaktadır (bunlar temelde aynıdır) çünkü cevap verirken çoğu insanın bu JVM'leri kullandığını söyleyebilirim. Java'nın 8 itibarıyla hafıza modelinde önemli değişiklikler, kudretini yukarıdaki ifadeleri Java 8 HotSpot doğru olmayabilir - ve bu yüzden, Java 7 HotSpot değişiklikleri kontrol etmedi tahmin yukarıdaki bu sürümün hala geçerlidir, ama burada emin değilim.


1
Ahh, statik değişkenlerden emin misin? AFAIK PermGen sadece tanımları kaydeder, gerçek değeri değil.
Amir Raminfar

2
@Amir Değişkenin kendisinin permgen alanında saklandığından oldukça eminim, başvurulan herhangi bir nesne büyük olasılıkla öbek üzerinde tahsis edilecektir. Bu, bazı bilgiler ekleyebilir: stackoverflow.com/questions/3800444/…
Thomas

1
Ah evet değişken tanımı permgen'de saklanır. Ancak değer yığın içinde olacaktır. Cevabınız, değerin PermGen'de de saklandığını öne sürdü.
Amir Raminfar

1
@Matthew cevabımı nasıl anlıyorsun? A, değişkenlerin başvurdukları nesnelerde değil permgen bölümünde (ilkeller / başvurular) depolandığını söyledi . Bir değişken değerini nasıl görüntülediğinize bağlıdır .
Thomas

1
@Nav, öbeğin tüm parçaları varsayılan olarak çöp olarak toplanmaz ve bazen sınıflar ve dolayısıyla statik değişkenler toplanamaz çünkü sınıf yükleyicileri üzerinde hala bir başvuru vardır. Ek olarak, çöp toplayıcının çalışmasına güvenmemelisiniz, çünkü bu tamamen JVM'ye bağlıdır (ne zaman çalıştırılacağına ve nelerin toplanacağına karar verir, yalnızca "Gc'yi şimdi çalıştırmanızı istiyorum" gibi ipuçları sağlayabilirsiniz :)) .
Thomas

25

Sınıf değişkenleri (Statik değişkenler), Class objecto sınıfla ilişkilendirilmiş olanın bir parçası olarak saklanır . Bu Class nesnesi yalnızca JVM tarafından oluşturulabilir ve içinde saklanır permanent generation.

Ayrıca bazıları, Method Area.bu yanıtın yanlış değil diye adlandırılan yığın dışı alanda depolandığını söylemiştir . Permgen Alanının yığının bir parçası olup olmadığı tartışmalı bir konudur. Açıkçası algılar kişiden kişiye farklılık gösterir. Bence JVM argümanlarında yığın alanı ve permgen alanını farklı şekilde sağlıyoruz. Bu nedenle, onlara farklı davranmak iyi bir varsayımdır.

Onu görmenin başka bir yolu

Bellek havuzları, çalışma süresi sırasında JVM bellek yöneticileri tarafından oluşturulur. Bellek havuzu, yığın veya yığın olmayan belleğe ait olabilir. Çalışma zamanı sabiti havuzu, bir sınıf dosyasındaki sabit_havuz tablosunun sınıf başına veya arabirim başına çalışma süresi gösterimidir. Her çalışma zamanı sabit havuzu, Java sanal makinesinin yöntem alanından tahsis edilir ve Statik Değişkenler bu Yöntem Alanında saklanır. Ayrıca bu non-heap, perm gen alanından başka bir şey değildir. Aslında Method alanı perm gen'in bir parçasıdır. ( Referans )

görüntü açıklamasını buraya girin


yöntem alanı, belleğin PermGen bölümünün bir alt kümesi değil mi? Bence bunlar (yöntem (sınıf) alanıyla birlikte PermGen) JVM'nin daha büyük yığın alanının parçası olduklarında, neden yığın olmayan belleğin bir parçası olarak yöntem alanını gösterdiniz?
Kaveesh Kanwal

Son satırı oku -Also this non-heap is nothing but perm gen area.Actually Method area is part of perm gen.
Aniket Thakur

1
@AniketThakur yöntem alanını yığın olmayan belleğin bir parçası olarak gösterdiniz, ancak oracle belgelerine göre burada, docs.oracle.com/javase/specs/jvms/se7/html/… , yöntem alanının mantıksal olarak yığın.
Karan

21

Java 8'den önce:

Statik değişkenler permgen uzayında saklandı (yöntem alanı da denir).

PermGen Space, Method Area olarak da bilinir.

PermGen Space 3 şeyi depolamak için kullanılırdı

  1. Sınıf düzeyinde veriler (meta veriler)
  2. dahili dizeler
  3. statik değişkenler

Java 8'den itibaren

Statik değişkenler Heap'in kendisinde saklanır. Java 8'den itibaren PermGen Space kaldırıldı ve MetaSpace olarak adlandırılan yeni alan, artık önceki Permgen Space'den farklı olarak Heap'in bir parçası olmayan yeni alan tanıtıldı. Meta-Space yerel bellekte mevcuttur (işletim sistemi tarafından belirli bir Uygulamaya kendi kullanımı için sağlanan bellek) ve artık yalnızca sınıf meta verilerini depolar.

İç içe geçmiş dizeler ve statik değişkenler, yığının kendisine taşınır.

Resmi bilgiler için bakınız: JEP 122: Kalıcı Gen Boşluğunu Çıkarın


statik değişkenler> Java8 için "kendini öbek" dediğinizde, tam olarak nerede: OldGen?
Ewoks

15

Bu, basit bir cevabı ve uzun soluklu bir cevabı olan bir sorudur.

Basit cevap yığın. Sınıflar ve sınıflara uygulanan tüm veriler (örnek verileri değil), yığının Kalıcı Üretim bölümünde depolanır.

Uzun cevap zaten yığın taşması üzerinedir:

Bir yoktur JVM bellek ve çöp toplama kapsamlı açıklama yanı sıra bu görüşmeler daha kısaca cevap bu konuda.


3
Tabi ki! Yararlı bulursanız bu adamlara oy vermeyi unutmayın.
Vasiliy Sharapov

11

Sınıf tanımının başvurduğu yığın içinde saklanır. Düşünürseniz, kapsam olmadığı için stack ile ilgisi yoktur.


5

Thomas'ın cevabına ek olarak, statik değişken, Yöntem Alanı adı verilen yığın olmayan alanda saklanır.


4

Statik değişkenler sınıf düzeyinde değişkenler olduğundan, yığın belleğinin " kalıcı üretimini " depolarlar . İçine bakmak Lütfen bu JVM daha fazla ayrıntı için. Bunun yardımcı olacağını umuyorum


3

statik değişkenler yığın içinde saklanır


7
Statik değişken PremGen alanında hafızada saklanır, değerleri Heap'de saklanır.
Akash5288
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.