ทำไมต้องมีค่าใช้จ่ายเมื่อจัดสรรออบเจ็กต์ / อาร์เรย์ใน Java


9

มีอาร์เรย์จำนวนเท่าใดใน Java? สมมติว่าเป็นเครื่อง 64 บิตและสมมติว่ามีองค์ประกอบ N ในอาร์เรย์ดังนั้นองค์ประกอบเหล่านี้จะใช้ 2 * N, 4 * N หรือ 8 * N ไบต์สำหรับอาร์เรย์ประเภทต่างๆ

และการบรรยายใน Coursera บอกว่ามันจะครอบครอง 2 * N + 24, 4 * N + 24 หรือ 8 * N + 24 ไบต์สำหรับอาร์เรย์องค์ประกอบ N และ 24 ไบต์เรียกว่าโอเวอร์เฮด แต่ไม่ได้อธิบายว่าทำไมโอเวอร์เฮดจึงเป็น จำเป็น

นอกจากนี้วัตถุยังมีค่าใช้จ่ายซึ่งเป็น 16 ไบต์

ค่าโสหุ้ยเหล่านี้คืออะไร? 24/16 ไบต์ประกอบด้วยอะไรบ้าง

นอกจากนี้ค่าโสหุ้ยเหล่านี้มีอยู่ใน Java ด้วยหรือไม่ แล้ว C, C ++ และ Python ล่ะ?


2
ตรวจสอบ: stackoverflow.com/a/258150/1029272
Deco

1
@Gnijuohz: คุณหมายถึงการถาม: ค่าใช้จ่ายนี้ประกอบด้วยข้อมูลอะไร?
FrustratedWithFormsDesigner

@ YanisRizos: ฉันคิดว่า OP ต้องการทราบว่าอะไรคือสิ่งที่อยู่ใน 24 ไบต์สำหรับอาร์เรย์
FrustratedWithFormsDesigner

@FrustratedWithFormsDesigner อ่าดูเหมือนจะตีความคำถามได้ดีกว่าของฉัน
yannis

@ YannisRizos ขอโทษเกี่ยวกับทัศนคติที่ไม่ดีของฉัน แต่เมื่อคุณโพสต์ลิงค์นั้นฉันอดไม่ได้ที่จะคิดว่ามันเป็นการถากถาง ป้องกันด้วยฉันเดา
Gnijuohz

คำตอบ:


16

แต่ละอ็อบเจ็กต์ Java มีส่วนหัวที่มีข้อมูลที่สำคัญสำหรับ JVM ที่สำคัญที่สุดคือการอ้างอิงถึงคลาสของวัตถุ (หนึ่งคำเครื่องจักร) และมีธงบางส่วนที่ใช้โดยตัวรวบรวมขยะและเพื่อจัดการการประสาน (ตั้งแต่วัตถุทุกคนสามารถทำข้อมูลให้ตรงกัน) ซึ่งใช้คำเครื่องอื่น (ใช้คำบางส่วนจะ แย่สำหรับประสิทธิภาพ) นั่นคือ 2 คำซึ่งคือ 8 ไบต์ในระบบ 32 บิตและ 16 ไบต์ใน 64 บิต อาเรย์ต้องมีฟิลด์ int สำหรับความยาวของอาเรย์ซึ่งเป็นอีก 4 ไบต์ซึ่งอาจเป็น 8 ในระบบ 64 บิต

สำหรับภาษาอื่น ๆ :

  • C ไม่มีวัตถุดังนั้นแน่นอนว่าไม่มีส่วนหัววัตถุ แต่อาจมีส่วนหัวในแต่ละส่วนของหน่วยความจำที่จัดสรรแยกต่างหาก

  • ใน C ++ คุณไม่ได้มีการรวบรวมขยะและไม่สามารถใช้วัตถุโดยพลการสำหรับการซิงโครไนซ์ แต่ถ้าคุณมีคลาสที่มีวิธีการแทนที่แต่ละวัตถุมีตัวชี้ไปยัง vtable เช่นเดียวกับการอ้างอิงของวัตถุ Java กับคลาสของมัน หากคุณใช้ตัวชี้สมาร์ทที่ทำการรวบรวมขยะพวกเขาต้องการข้อมูลการดูแลทำความสะอาด

  • ฉันไม่รู้เกี่ยวกับ Python แต่ฉันค่อนข้างแน่ใจว่ามันต้องมีการอ้างอิงถึงคลาสและข้อมูลการทำความสะอาดสำหรับตัวเก็บขยะ


มีงานที่เกิดขึ้นใน OpenJDK ในขณะนี้เพื่อลดขนาดของส่วนหัวของวัตถุ, ขั้นตอนเล็ก ๆ แต่มีความสำคัญ :-)
Martijn Verburg

ใน C ++ คลาส polymorphic เท่านั้นที่ต้องการ vtables std::pair<int, float>เป็นคลาสธรรมดาที่ไม่ต้องการ vtable เลย ผลก็คือมันอาจจะพอดีกับ 8 ไบต์ นอกจากนี้ตัวชี้อัจฉริยะไม่จำเป็นต้องเพิ่มการดูแลทำความสะอาด ตัวอย่างเคาน์เตอร์ที่ชัดเจนคือstd::unique_ptr<T>ซึ่งโดยทั่วไปจะใหญ่พอ ๆ กับดิบT*(Unique_ptr แน่นอนไม่ได้ทำ GC)
MSalters

4
C มีโอเวอร์เฮดแต่ละmallocบล็อกจัดสรรหน่วยความจำต้องการส่วนหัวที่freeใช้
herby

อย่างน้อยหนึ่งไลบรารี malloc ที่ฉันรู้ใช้ 8-byte header บนระบบ 32- บิต (ซึ่งเป็นความยาว 4-byte bracketed โดยสอง Sentinel 2-byte ค่า IIRC)
Donal Fellows
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.