ukuran boolean tidak didefinisikan dalam java: mengapa?

10

Saya melihat ukuran boolean tidak ditentukan. Di bawah ini adalah dua pernyataan yang saya lihat pada ukuran data primitif java

tidak didefinisikan secara tepat

Penjelasan lebih lanjut mengatakan

boolean mewakili sedikit informasi, tetapi "ukurannya" bukanlah sesuatu yang didefinisikan secara tepat.

Pertanyaan muncul di benak saya adalah mengapa boolean di java tidak dapat direpresentasikan dengan 1 bit (atau 1 byte jika byte adalah representasi minimum)?

Tapi saya melihat itu sudah dijawab di /programming/1907318/why-is-javas-boolean-primitive-size-not-d-dined di mana dikatakan

JVM menggunakan sel stack 32-bit, yang digunakan untuk menyimpan variabel lokal, argumen metode, dan nilai ekspresi. Primitif yang lebih kecil dari 1 sel diisi, primitif lebih besar dari 32 bit (panjang dan ganda) mengambil 2 sel

Apakah ini berarti tipe data byte / char / short primitiva pendek juga membutuhkan 32 bit meskipun ukurannya didefinisikan sebagai 8/16/16 bit?

Juga dapatkah kita mengatakan ukuran boolean akan menjadi 32 bit pada cpu 32 bit dan 64 bit pada cpu 64 bit?

pengguna3222249
sumber
Does it mean even byte/char/short primitiva data types also take 32 bit though their size is defined as 8/16/16 bit ?-- Iya.
Robert Harvey
Also can we say boolean size will be 32 bit on 32 bit cpu and 64 bit on 64 bit cpu ?- Tidak. Ukurannya ditentukan oleh JVM.
Robert Harvey
@RobertHarvey Jika tipe data byte / char / short primitivee juga membutuhkan 32 bit lalu apa gunanya mendefinisikan ukurannya sebagai 8/16/16 bit di java?
user3222249
Sehingga mereka dapat disimpan lebih efisien dalam array.
Robert Harvey

Jawaban:

11

TL; DR Satu-satunya hal yang pasti adalah yang booleanmenempati setidaknya satu bit. Segala sesuatu yang lain tergantung pada implementasi JVM.

Spesifikasi Bahasa Jawa tidak menentukan ukuran, hanya rentang nilai (lihat Spesifikasi Bahasa ). Jadi, ini bukan hanya booleanukuran yang tidak ditentukan pada level ini. Dan booleanmemiliki dua nilai yang mungkin: falsedan true.

The Virtual Machine Spesifikasi memberitahu kita bahwa booleanvariabel diperlakukan seperti intdengan nilai 0 dan 1. Hanya array booleanmemiliki dukungan khusus. Jadi pada tingkat Mesin Virtual, booleanvariabel menempati jumlah ruang yang sama dengan int, artinya satu tumpukan sel: setidaknya 4 byte, biasanya 4 byte pada Java 32-bit dan 8 byte pada 64-bit.

Akhirnya ada mesin HotSpot yang mengkompilasi bytecode JVM ke dalam kode mesin CPU-dioptimalkan, dan saya bertaruh bahwa dalam banyak kasus itu mampu menyimpulkan kisaran nilai terbatas int-masked booleandari konteks dan menggunakan ukuran yang lebih kecil.

Ralf Kleberhoff
sumber
Seperti robert dan Anda juga secara tidak langsung mengatakan bahwa Jika byte / char / tipe data primitif pendek juga memakan waktu 32 bit maka pertanyaan saya adalah apa gunanya mendefinisikan ukuran mereka sebagai 8/16/16 bit di java?
user3222249
Titik untuk menentukan kisaran nilai terbatas mereka (atau "ukuran", jika Anda mau) adalah semantik mereka, misalnya membungkus sekitar 127 hingga -128. Seringkali itu tidak diinginkan, tetapi terkadang bermanfaat. Dan kemudian ada array dari tipe yang lebih pendek, dan mereka benar-benar menempati ruang lebih sedikit daripada array int. Dan akhirnya ada potensi mesin JIT compiler / HotSpot untuk mengoptimalkan ruang hingga kurang dari 4 byte.
Ralf Kleberhoff
8

Ada beberapa konsep yang perlu digali:

  • bahasa pemrograman Java itu sendiri, yang merupakan bahasa pemrograman tekstual,
  • format file kode-byte & kelas Java Java Machine , yang merupakan pengkodean biner yang dikompilasi dari kode sumber bahasa Java asli, dan digunakan sebagai format file interchange untuk menyimpan, memuat, dan berbagi kode objek java,
  • implementasi Java Virtual Machine tertentu , yang bisa menjadi juru bahasa meskipun seringkali bukan implementasi berbasis JIT,
  • JIT menghasilkan kode mesin yang berjalan langsung pada prosesor perangkat keras.

Java, bahasa pemrograman , tidak mendefinisikan ukuran konsep tipe primitif karena (tidak seperti C / C ++) tidak ada sizeofoperator: ukuran tidak dapat diamati melalui konstruksi bahasa, sehingga bahasa tidak perlu mendefinisikannya.

Seperti @Ralf tunjukkan bahasa Java tidak menentukan kisaran tipe primitif, yang sangat relevan bagi programmer karena rentang ini dapat diamati melalui konstruk dalam bahasa.

Bahasa tidak mendefinisikan kemampuan instrumentasi yang memungkinkan penyelidikan ke ukuran objek, tetapi (1) ini membutuhkan instrumentasi, (2) hanya memberikan perkiraan, dan (3) penyelidikan ini tidak berlaku untuk tipe primitif atau variabel lokal.

JVM menggunakan sel stack 32-bit, yang digunakan untuk menyimpan variabel lokal, argumen metode, dan nilai ekspresi. Primitif yang lebih kecil dari 1 sel diisi, primitif lebih besar dari 32 bit (panjang dan ganda) mengambil 2 sel

Kutipan padding berbicara dengan detail format file kelas JVM, yang digunakan sebagai mekanisme pertukaran (berbeda dari bahasa Jawa dan implementasi JVM). Meskipun apa yang dikatakannya berlaku untuk mesin abstrak dan kode byte JVM, itu tidak harus berlaku untuk kode mesin JIT'ed.

Kutipan padding juga membatasi dirinya untuk diskusi variabel / parameter / ekspresi lokal yang biasanya ditumpuk dialokasikan (misalnya otomatis atau otomatis dalam C / C ++), dan tidak membahas objek / array.

Ukuran aktual dari variabel otomatis semacam itu hampir tidak pernah menjadi masalah (misalnya untuk kinerja atau untuk ruang).

Sebagian, ini karena CPU perangkat keras yang mendasarinya lebih alami bekerja pada ukuran bit yang lebih besar (seperti 32 atau 64) daripada 1-bit. Bahkan ukuran 8 atau 16 bit umumnya tidak lebih cepat dari 32, dan kadang-kadang penanganan 8-bit memerlukan satu atau dua instruksi tambahan untuk bekerja dengan register set perangkat keras yang lebih luas.

Dan alasan lain adalah terbatasnya penggunaan variabel lokal - mereka digunakan secara langsung oleh kode dan hanya dengan kode, dan dengan demikian tidak benar-benar tunduk pada masalah penskalaan - khususnya, dibandingkan dengan objek dan array, yang digunakan oleh struktur data berpotensi skala apa pun .

(Kami mungkin menganggap rekursi sebagai penskalaan variabel lokal, jadi variabel lokal yang lebih besar dalam rutinitas rekursif berisiko menumpuk lebih cepat.)

Namun, ukuran objek bisa sangat berarti, jika jumlah instance tinggi, dan juga, ukuran elemen array dapat menjadi masalah jika memiliki jumlah elemen yang tinggi.


Apakah ini berarti tipe data byte / char / short primitiva pendek juga membutuhkan 32 bit meskipun ukurannya didefinisikan sebagai 8/16/16 bit?

Untuk penduduk setempat, mungkin, mungkin tidak tergantung pada JIT.

Untuk objek, dalam kode byte JVM & mekanisme file kelas, bidang secara langsung diakses oleh identifikasi mereka dan tidak ada gagasan yang diberikan tentang "sel" - sedangkan ada dengan variabel (lokal dan parameter).

Implementasi JVM (termasuk JIT) memiliki fleksibilitas untuk mengatur ulang urutan bidang dalam implementasi (misalnya pada level kode mesin) sehingga dua bidang 16-bit dapat menempati kata 32-bit yang sama bahkan jika tidak dinyatakan secara terpisah dalam kode sumber. ; ini mengurangi overhead yang disebabkan oleh padding yang diperlukan untuk mempertahankan perataan. Setiap perubahan, padding, dan penempatan bidang seperti itu juga sangat spesifik untuk implementasi JVM daripada format interchange JVM. Secara teori, JIT dapat mengemas boolean menjadi satu-bit dalam sebuah array, atau mengemas 8 bidang boolean individu ke dalam satu byte tunggal dalam suatu objek. Yang paling tidak dilakukan adalah pilihan implementasi JVM.

Erik Eidt
sumber