Di mana metode statis dan variabel statis disimpan di Java?

115

Sebagai contoh:

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;
    }
}

Di mana variabel ini akan disimpan di Java, di heap, atau di memori tumpukan? Bagaimana cara menyimpannya?

Nav
sumber
2
tautan yang sangat berguna untuk memahami pengumpulan Sampah di situs resmi Oracle: oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/…
Arnav Joshi

Jawaban:

144

Metode statis (sebenarnya semua metode) serta variabel statis disimpan di PermGenbagian heap, karena mereka adalah bagian dari data refleksi (data terkait kelas, bukan terkait instance).

Pembaruan untuk klarifikasi :

Perhatikan bahwa hanya variabel dan nilai teknisnya (primitif atau referensi) yang disimpan di ruang PermGen.

Jika variabel statis Anda adalah referensi ke objek, objek itu sendiri disimpan di bagian normal heap (generasi muda / tua atau ruang penyintas). Objek-objek tersebut (kecuali mereka adalah objek internal seperti kelas dll.) Tidak disimpan di ruang PermGen.

Contoh:

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.


Sepatah kata tentang pengumpulan sampah:

Jangan tidak mengandalkan finalize()seperti itu tidak dijamin untuk menjalankan. Ini sepenuhnya tergantung pada JVM untuk memutuskan kapan menjalankan pengumpul sampah dan apa yang harus dikumpulkan, bahkan jika suatu objek memenuhi syarat untuk pengumpulan sampah.

Tentu saja Anda bisa menyetel variabel statis ke null dan dengan demikian menghapus referensi ke objek di heap, tetapi itu tidak berarti pengumpul sampah akan mengumpulkannya (meskipun tidak ada referensi lagi).

Selain finalize()itu dijalankan hanya sekali, jadi Anda harus memastikan itu tidak membuang pengecualian atau mencegah objek untuk dikumpulkan. Jika Anda menghentikan penyelesaian melalui beberapa pengecualian, finalize()tidak akan dipanggil pada objek yang sama untuk kedua kalinya.

Catatan terakhir : bagaimana kode, data runtime, dll. Disimpan tergantung pada JVM yang digunakan, misalnya HotSpot mungkin melakukannya secara berbeda dari JRockit dan ini bahkan mungkin berbeda di antara versi JVM yang sama. Di atas didasarkan pada HotSpot untuk Java 5 dan 6 (pada dasarnya sama) karena pada saat menjawab saya akan mengatakan bahwa kebanyakan orang menggunakan JVM tersebut. Karena perubahan besar dalam model memori pada Java 8, pernyataan di atas mungkin tidak benar untuk Java 8 HotSpot - dan saya tidak memeriksa perubahan Java 7 HotSpot, jadi saya rasa hal di atas masih berlaku untuk versi itu, tapi saya tidak yakin di sini.

Thomas
sumber
1
Ahh apakah Anda yakin tentang variabel statis? AFAIK PermGen hanya menyimpan definisi, bukan nilai sebenarnya.
Amir Raminfar
2
@Amir Saya cukup yakin bahwa variabel itu sendiri disimpan di ruang permgen, objek referensi apa pun kemungkinan besar akan dialokasikan di heap. Ini mungkin menambahkan beberapa informasi: stackoverflow.com/questions/3800444/…
Thomas
1
Ah ya definisi variabel disimpan di permgen. Tapi nilainya akan ada di heap. Jawaban Anda menunjukkan bahwa nilainya juga disimpan di PermGen.
Amir Raminfar
1
@Matthew bagaimana Anda memahami jawaban saya? A mengatakan bahwa variabel disimpan di bagian permgen (primitif / referensi) bukan objek yang dirujuknya. Itu tergantung pada bagaimana Anda melihat nilai variabel .
Thomas
1
@Nav tidak semua bagian dari heap adalah sampah yang dikumpulkan secara default dan terkadang kelas dan dengan demikian variabel statis tidak dapat dikumpulkan karena pemuat kelas masih memiliki referensi padanya. Selain itu, Anda tidak boleh mengandalkan pengumpul sampah untuk menjalankannya karena itu sepenuhnya bergantung pada JVM (ini memutuskan kapan harus menjalankan dan apa yang harus dikumpulkan, Anda hanya dapat memberikan petunjuk seperti "Saya ingin Anda menjalankan gc sekarang" :)) .
Thomas
25

Variabel kelas (variabel statis) disimpan sebagai bagian dari yang Class objectterkait dengan kelas itu. Objek Kelas ini hanya dapat dibuat oleh JVM dan disimpan di permanent generation.

Juga ada yang menjawab bahwa itu disimpan di area non heap yang disebut Method Area.Bahkan jawaban ini tidak salah. Ini hanya topik yang bisa diperdebatkan apakah Permgen Area adalah bagian dari heap atau bukan. Jelas, persepsi berbeda dari orang ke orang. Menurut pendapat saya, kami memberikan ruang heap dan ruang permgen berbeda dalam argumen JVM. Jadi adalah asumsi yang baik untuk memperlakukan mereka secara berbeda.

Cara lain untuk melihatnya

Pool memori dibuat oleh manajer memori JVM selama runtime. Pool memori dapat dimiliki oleh memori heap atau non-heap. Kumpulan konstanta waktu proses adalah representasi run time per kelas atau per antarmuka dari tabel constant_pool dalam file kelas. Setiap kumpulan konstan runtime dialokasikan dari area metode mesin virtual Java dan Variabel Statis disimpan di Area Metode ini. Juga non-heap ini tidak lain adalah area perm gen. Sebenarnya area Metode adalah bagian dari perm gen. ( Referensi )

masukkan deskripsi gambar di sini

Aniket Thakur
sumber
apakah area metode bukan bagian dari bagian PermGen dari memori? Mengapa Anda menunjukkan area metode sebagai bagian dari memori non-heap ketika, menurut saya, mereka (PermGen bersama dengan area metode (kelas)) adalah bagian dari area heap yang lebih besar dari JVM?
Kaveesh Kanwal
Baca baris terakhir -Also this non-heap is nothing but perm gen area.Actually Method area is part of perm gen.
Aniket Thakur
1
@AniketThakur Anda telah menunjukkan area metode sebagai bagian dari memori non-heap tetapi menurut dokumen oracle, di sini, docs.oracle.com/javase/specs/jvms/se7/html/… , disebutkan bahwa area metode secara logis merupakan bagian dari tumpukan.
Karan
21

Sebelum Java 8:

Variabel statis disimpan di ruang permgen (juga disebut area metode).

PermGen Space juga dikenal sebagai Area Metode

PermGen Space digunakan untuk menyimpan 3 benda

  1. Data tingkat kelas (meta-data)
  2. string internal
  3. variabel statis

Dari Java 8 dan seterusnya

Variabel statis disimpan di Heap itu sendiri. Dari Java 8 dan seterusnya, PermGen Space telah dihapus dan ruang baru bernama MetaSpace diperkenalkan yang bukan merupakan bagian dari Heap lagi seperti Permgen Space sebelumnya. Meta-Space hadir di memori asli (memori yang disediakan oleh OS ke Aplikasi tertentu untuk penggunaannya sendiri) dan sekarang hanya menyimpan meta-data kelas.

String internal dan variabel statis dipindahkan ke heap itu sendiri.

Untuk informasi resmi, lihat: JEP 122: Hapus Ruang Gen Permanen

Manish Kumar
sumber
saat Anda mengatakan "tumpukan itu sendiri" untuk variabel statis> Java8, di mana tepatnya: OldGen?
Ewoks
15

Ini adalah pertanyaan dengan jawaban sederhana dan jawaban bertele-tele.

Jawaban sederhananya adalah heap. Kelas dan semua data yang berlaku untuk kelas (bukan data contoh) disimpan di bagian Generasi Permanen dari heap.

Jawaban panjangnya sudah di stack overflow:

Ada deskripsi lengkap tentang memori dan pengumpulan sampah di JVM serta jawaban yang berbicara lebih ringkas tentangnya.

Vasiliy Sharapov
sumber
3
Tentu! Jangan lupa untuk memberi suara positif pada orang-orang itu jika Anda merasa berguna.
Vasiliy Sharapov
11

Itu disimpan di heap yang direferensikan oleh definisi kelas. Jika Anda memikirkannya, ini tidak ada hubungannya dengan tumpukan karena tidak ada ruang lingkup.

Amir Raminfar
sumber
5

Selain jawaban Thomas, variabel statis disimpan di area non heap yang disebut Area Metode.

Vipin
sumber
4

Karena variabel statis adalah variabel tingkat kelas, mereka akan menyimpan " generasi permanen " memori heap. Silakan lihat ini untuk detail lebih lanjut tentang JVM. Berharap ini bisa membantu

Ramesh Papaganti
sumber
3

variabel statis disimpan di heap

CLS
sumber
7
Variabel statis disimpan di ruang PremGen di memori, nilainya disimpan di Heap.
Akash5288