هل تساءلت يوما كيف تبدو كائنات جافا من الداخل؟
تحت القط ، سيكون هناك وصف مفصل لرأس كائن java ، وما يتكون منه ومقدار الذاكرة التي يحتاجها.
بادئ ذي بدء ، تذكر أن أي كائن في الذاكرة في jvm يتكون من رأس الكائن ومتغيرات الكائن (الروابط والأولويات). أيضا ، يمكن توسيع الحجم النهائي للكائن ليصبح مضاعف 8 بايت.
يتكون عنوان كل كائن (باستثناء الصفيف) من كلمتين آليتين - علامة الكلمة وكلمة الفئة . تحتوي المصفوفات على 32 بت إضافي لوصف طول المصفوفة.
يخزن وضع علامة لكلمة رمز التجزئة للهوية ، البتات التي يستخدمها جامع البيانات المهملة ، والبتات المستخدمة للأقفال. يمكنك دائمًا العثور على مزيد من التفاصيل في أنواع OpenJDK المقابلة markOop.hpp .
تقوم كلمة الفصل بتخزين مؤشر للفئة نفسها ، أي إلى المكان الذي توجد فيه معلومات حول نوع البيانات هذا: الأساليب ، والشروح ، والميراث ، وأكثر من ذلك. يمكن أيضًا العثور على مزيد من التفاصيل في أنواع OpenJDK المقابلة من klass.hpp .
دعونا الآن نلقي نظرة فاحصة على عنوان الكائن ، وعلى وجه التحديد كلمة علامة
32 بت jvm

كما ترون من الجدول ، يمكن أن يختلف محتوى علامة الكلمة اختلافًا كبيرًا حسب الحالة الحالية للكائن.
الحالة الطبيعية للكائن (biased_lock = 0 ، القفل = 01)
- Identification_hashcode هو تجزئة كائن يظهر بتكاسل. إذا كان الكائن يحتوي على استدعاء System.identityHashCode (obj) لأول مرة ، فسيتم حساب هذه التجزئة وكتابتها على رأس الكائن.
في حالات أخرى ، عندما تتنافس التدفقات المختلفة على كائن ما ، سيتم تخزين كود هوية رمز الهوية ليس في رأس الكائن ، ولكن في شاشة الكائن. - العمر - عدد مجموعات القمامة من ذوي الخبرة. عندما يصل العمر إلى الحد الأقصى لعدد الحيازة ،
ينتقل الكائن إلى منطقة الورك من الجيل القديم. - biased_lock - يحتوي على 1 إذا تم تمكين قفل متحيز لهذا الكائن ، وإلا 0.
أكثر قليلاعند تشغيل Biased Locking ، ينتقل الكائن كما كان إلى الكائن الأول الذي استولى على شاشته. سيكون التقاط اللاحقة الكائن في نفس الدفق أسرع قليلاً.
فيما يلي المتطلبات الأساسية النظرية لهذا القفل:
- طوال عمر كائن ما ، فإنه مملوك في الغالب بواسطة دفق واحد
- إذا كان مؤشر الترابط قد استخدم مؤخرًا قفلًا لهذا الكائن ، فمن المرجح أن ذاكرة التخزين المؤقت للمعالج ستظل تحتوي على البيانات اللازمة لإعادة التقاط هذا الكائن.
يتم تمكين Biased Locking افتراضيًا منذ java 6 ، -XX: -UseBiasedLocking
- قفل - يحتوي على رمز حالة القفل. 00 - مقفلة خفيفة الوزن ، 01 - غير مقفلة أو منحازة ، 10 - مقفلة الوزن الثقيل ، 11 - مخصصة لجمع القمامة.
وهذا هو ، في الجدول ، يتم تحديد حالة الكائن عن طريق الجمع بين بت biased_lock وقفل.
وضع مغلق متحيز (biased_lock = 1 ، قفل = 01)
- مؤشر الترابط - في وضع قفل متحيز ، من المفترض أن الكائن مملوك في الغالب من خلال مؤشر ترابط معين ، يتم تخزين معرف مؤشر الترابط هذا في الحقل.
- epoch يحتوي على بعض المؤشرات المؤقتة لملكية الكائن من خلال سلسلة رسائل يتم تخزين معرفها في سلسلة رسائل
وضع القفل الخفيف (القفل = 00)
في هذا الوضع ، من المفترض أن وقت الالتقاط بواسطة هذا الكائن من خلال تدفقات مختلفة لا يتقاطع على الإطلاق أو لا يتداخل بشكل ضئيل. في هذا الوضع ، بدلاً من حظر نظام التشغيل بشكل كبير ، يستخدم JVM الذرات.
- ptr_to_lock_record - يتم استخدام CAS (مقارنة وتعيين) داخل حلقة الدوران لتعيين / انتظار القفل.
كمرجع ، سيكون الحد الأدنى لوقت حظر نظام التشغيل في المنطقة حوالي 10 مللي ثانية ، بمساعدة الذرات ، لا ينام التيار ، لكنه يستمر في تحديد دورة صغيرة ، وبمجرد أن يكون المورد مجانيًا ، ستنتهي الدورة الذرية وسيلتقط الدفق هذا الكائن على الفور.
وضع القفل الثقيل (القفل = 10)
- ptr_to_heavyweight_monitor - إذا كان وقت التقاط هذا الكائن بتدفقات مختلفة سيتداخل بشكل كبير ، فسيتم استبدال القفل الخفيف بقفل للوزن الثقيل. سيتم كتابة مؤشر على الشاشة إلى ptr_to_heavyweight_monitor. يستخدم قفل نظام التشغيل.
حتى في 32 بت jvm رأس الكائن يتكون من 8 بايت. صفائف بالإضافة إلى ذلك 4 بايت.
64 بت jvm

على jvm 64 بت ، يتكون رأس الكائن من 16 بايت. صفائف بالإضافة إلى ذلك 4 بايت.
jvm 64 بت مع ضغط المؤشر

يتكون رأس الكائن من 12 بايت. صفائف بالإضافة إلى ذلك 4 بايت.
قليلا عن ضغط المؤشر. لمؤشر 32 بت ، تقتصر مساحة العنوان على 4 غيغابايت. ومع ذلك ، إذا تذكرنا مرة أخرى أنه في jvm حجم كائن ما هو مضاعف 8 بايت ، فيمكننا استخدام مؤشر زائف 35 بت ، مع ثلاثة أصفار في النهاية. وبالتالي ، تشير بالفعل إلى 32GB من الذاكرة. الضغط ليس مجانيًا ، فالسعر هو عملية إضافية (المؤشر << 3) لأي مكالمة إلى الكومة.
رابط إلى المقال الأصلي:
جافا كائن رأس
أود أيضًا أن أضيف أن كل شيء موصوف هنا ليس عقيدة ، ربما في إصدارات أخرى من jvm سيكون عنوان الكائن مختلفًا. الموصوفة هنا ذات صلة بـ openjdk 8.