Mengapa overhead saat mengalokasikan objek / array di Jawa?

9

Berapa byte yang menempati array di Jawa? Asumsikan Ini adalah mesin 64bit dan juga mengasumsikan ada elemen N dalam array, sehingga semua elemen ini akan memakan 2 * N, 4 * N atau 8 * N byte untuk berbagai jenis array.

Dan sebuah ceramah di Coursera mengatakan bahwa itu akan menempati 2 * N + 24, 4 * N + 24 atau 8 * N + 24 byte untuk array elemen N dan 24 byte disebut overhead, tetapi tidak menjelaskan mengapa overhead itu dibutuhkan.

Objek juga memiliki overhead, yaitu 16 byte.

Apa sebenarnya overhead ini? Terdiri dari apakah 24/16 byte ini?

Juga, apakah overhead ini hanya ada di Jawa? Bagaimana dengan C, C ++ dan Python?

Gnijuohz
sumber
1
@ Gnijuohz: Maksud Anda bertanya: dari data apa overhead ini dibuat?
FrustratedWithFormsDesigner
@YannisRizos: Saya pikir OP ingin tahu apa yang sebenarnya ada dalam 24 byte, untuk array.
FrustratedWithFormsDesigner
@FrustratedWithFormsDesigner Ah, itu tampaknya menjadi interpretasi yang lebih baik dari pertanyaan saya.
yannis
@YannisRizos menyesal tentang sikap buruk saya. Tetapi ketika Anda memposting tautan itu, saya pikir itu semacam sarkasme. Kurasa terlalu defensif.
Gnijuohz

Jawaban:

16

Setiap objek Java memiliki header yang berisi informasi penting untuk JVM. Yang paling penting adalah referensi ke kelas objek (satu kata mesin), dan ada beberapa bendera yang digunakan oleh pengumpul sampah dan untuk mengelola sinkronisasi (karena setiap objek dapat disinkronkan) yang membutuhkan kata mesin lain (menggunakan kata parsial akan buruk untuk kinerja). Jadi itu 2 kata, yaitu 8 byte pada sistem 32 bit, dan 16 byte pada 64 bit. Array juga membutuhkan bidang int untuk panjang array, yang merupakan 4 byte, mungkin 8 pada sistem 64 bit.

Adapun bahasa lain:

  • C tidak memiliki objek, jadi tentu saja tidak memiliki header objek - tetapi mungkin memiliki header pada setiap bagian memori yang dialokasikan secara terpisah.

  • Di C ++, Anda tidak memiliki pengumpulan sampah dan tidak dapat menggunakan objek arbitrer untuk sinkronisasi, tetapi jika Anda memiliki kelas dengan metode yang diganti, setiap objek memiliki pointer ke vtable, seperti referensi objek Java ke kelasnya. Jika Anda menggunakan pointer pintar yang melakukan pengumpulan sampah, mereka membutuhkan data housekeeping.

  • Saya tidak tahu tentang Python, tapi saya cukup yakin itu juga perlu referensi ke kelas, dan informasi rumah tangga untuk pengumpul sampah.

Michael Borgwardt
sumber
Ada pekerjaan yang terjadi di OpenJDK saat ini untuk mengurangi ukuran header objek, langkah-langkah kecil tapi penting :-)
Martijn Verburg
Dalam C ++, hanya kelas polimorfik yang membutuhkan vtables. std::pair<int, float>adalah kelas sederhana yang tidak memerlukan vtable sama sekali. Sebagai hasilnya, itu mungkin sangat cocok dalam 8 byte. Juga, pointer pintar sebenarnya tidak perlu menambahkan housekeeping. Contoh tandingan yang jelas adalah std::unique_ptr<T>, yang biasanya sama besarnya dengan yang mentah T*(unique_ptr tentu saja tidak melakukan GC).
MSalters
4
C juga memiliki overhead, setiap mallocblok memori yang dialokasikan membutuhkan header yang freekemudian digunakan.
herby
Setidaknya satu perpustakaan malloc yang saya tahu menggunakan header 8-byte pada sistem 32-bit (yang merupakan panjang 4-byte yang dikurung oleh dua set nilai sentinel 2-byte, IIRC).
Donal Fellows