Java'da nesneleri / dizileri ayırırken neden ek yük?


9

Java'da bir dizi kaç bayt kaplar? 64bit bir makine olduğunu ve bir dizide N öğesinin olduğunu varsayalım, bu nedenle tüm bu öğeler farklı dizi türleri için 2 * N, 4 * N veya 8 * N bayt alacaktır.

Coursera'daki bir ders, bir N element dizisi için 2 * N + 24, 4 * N + 24 veya 8 * N + 24 bayt içereceğini ve 24 baytın tepeden çağrıldığını söylüyor, ancak ek yükün neden olduğunu açıklamıyor gerekli.

Ayrıca nesnelerin 16 baytlık ek yükleri vardır.

Bu genel giderler tam olarak nedir? Bu 24/16 bayt nelerden oluşuyor?

Ayrıca, bu ek yükler yalnızca Java'da mı bulunur? C, C ++ ve Python'a ne dersiniz?



1
@Gnijuohz: Şunu sormak istiyor musunuz: bu yük hangi verilerden oluşuyor?
FrustratedWithFormsDesigner

@YannisRizos: Bence OP diziler için 24 baytta aslında ne olduğunu bilmek istiyor.
FrustratedWithFormsDesigner

@FrustratedWithFormsDesigner Ah, bu soru benimkinden daha iyi bir yorum gibi görünüyor.
yannis

@YannisRizos kötü tutumum için üzgünüm. Ama bu bağlantıyı gönderdiğinde yardım edemem ama bunun bir çeşit alaycılık olduğunu düşünüyorum. Sanırım çok savunmacı.
Gnijuohz

Yanıtlar:


16

Her Java nesnesinin JVM için önemli bilgiler içeren bir başlığı vardır. En önemlisi, nesnenin sınıfına bir referanstır (bir makine sözcüğü) ve çöp toplayıcı tarafından ve senkronizasyonu yönetmek için (her nesne senkronize edilebildiğinden) başka bir makine kelimesini (kısmi kelimeler kullanarak performans için kötü olmak). Yani bu 32 bit sistemde 8 bayt ve 64 bitte 16 bayt olan 2 kelimedir. Diziler ayrıca dizi uzunluğu için bir int alanına ihtiyaç duyar, bu da başka bir 4 bayt, muhtemelen 64 bit sistemlerde 8'dir.

Diğer dillere gelince:

  • C'nin nesneleri yoktur, bu yüzden elbette nesne başlıkları yoktur - ancak ayrı olarak ayrılan her bellek parçasında bir başlık olabilir.

  • C ++ 'da, çöp toplama yoktur ve eşitleme için rasgele nesneler kullanamazsınız, ancak geçersiz kılınmış yöntemlere sahip sınıflarınız varsa, her nesnenin tıpkı Java nesnesinin sınıfına başvurusu gibi vtable için bir işaretçisi vardır. Çöp toplama işlemi yapan akıllı işaretçiler kullanırsanız, bunların temizlik verilerine ihtiyaç duyarlar.

  • Python hakkında bir bilgim yok, ama aynı zamanda sınıfa ve çöp toplayıcısına ait temizlik bilgilerine de ihtiyaç duyduğundan eminim.


Şu anda OpenJDK'da nesne başlıklarının boyutunu azaltmak için çalışmalar var, küçük ama önemli adımlar :-)
Martijn Verburg

C ++ 'da, sadece polimorfik sınıfların vtable ihtiyacı vardır. std::pair<int, float>hiç bir şeye ihtiyaç duymayan basit bir sınıftır. Sonuç olarak, 8 bayta çok iyi uyuyor olabilir. Ayrıca, akıllı işaretçilerin aslında temizlik eklemesine gerek yoktur. Net bir karşı örnek, std::unique_ptr<T>tipik olarak ham kadar büyüktür T*(unique_ptr elbette GC yapmaz).
MSalters

4
C'nin ayrıca bir tepegöz vardır, her bir mallocayrılmış bellek bloğunun freedaha sonra kullanan bir başlığa ihtiyacı vardır .
herby

Bildiğim en az bir malloc kütüphanesi, 32-bit sistemlerde 8 baytlık bir başlık kullanır (bu, 2 baytlık sentinel değerinin iki seti, IIRC ile parantezlenmiş 4 baytlık bir uzunluktur).
Donal Fellows
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.