1. المفاهيم الأساسية
سيقوم كل برنامج Java بإنشاء عملية Java. قد تحتوي كل عملية Java على واحد أو أكثر من خيوط. تتوافق كل عملية Java مع مثيل JVM فريد من نوعه ، كل مثيل JVM يتوافق مع كومة ، وكل مؤشر ترابط له مكدس خاص به. يتم وضع جميع حالات الفئات (أي الكائنات) أو المصفوفات (في إشارة إلى الصفيف نفسه ، وليس المراجع) التي أنشأتها عملية ما في الكومة ومشاركتها من قبل جميع مؤشرات الترابط من العملية. يتم تهيئة ذاكرة الكومة المخصصة في Java تلقائيًا ، أي عند تخصيص الذاكرة لكائن ما ، سيتم تهيئة المتغيرات في الكائن. على الرغم من أن مساحة التخزين لجميع الكائنات في Java مخصصة في الكومة ، يتم تخصيص الإشارة إلى هذا الكائن في المكدس ، أي عند إنشاء كائن ، يتم تخصيص الذاكرة في الكومة والمكدس. تخزن الذاكرة المخصصة في الكومة الكائن الذي تم إنشاؤه نفسه بالفعل ، بينما تخزن الذاكرة المخصصة في المكدس المراجع فقط إلى كائن الكومة. عندما يخرج المتغير المحلي الجديد ، يتم تخصيص المساحة في مساحة المكدس ومساحة الكومة. عندما تنتهي دورة الحياة المتغيرة المحلية ، يتم إعادة تدوير مساحة المكدس على الفور ، وينتظر مساحة مساحة الكومة لإعادة تدوير GC.
مفهوم محدد: يمكن تقسيم ذاكرة JVM إلى ثلاثة مجالات: الكومة ، المكدس والطريقة (الطريقة ، تسمى أيضًا المنطقة الثابتة):
منطقة المكدس:
1. جميعها مخزنة هي الكائنات ، وكل كائن يحتوي على معلومات مقابلة لها (الغرض من الفصل هو الحصول على تعليمات التشغيل) ؛
2. jvm يحتوي على مساحة واحدة فقط (كومة) ويتم مشاركتها من قبل جميع المواضيع. لا يقوم الكومة بتخزين الأنواع الأساسية ومراجع الكائنات ، ولكن فقط الكائن نفسه والمصفوفة نفسها ؛
منطقة المكدس:
1. كل مؤشر ترابط يحتوي على منطقة مكدس ، والتي تحفظ فقط الإشارات إلى نوع البيانات الأساسية نفسها والكائنات المخصصة ؛
2. البيانات (النوع البدائي ومرجع الكائن) في كل مكدس خاص ولا يمكن الوصول إليه بواسطة أكوام أخرى ؛
3. يتم تقسيم المكدس إلى 3 أجزاء: المنطقة الأساسية المتغيرة ، وسياق بيئة التنفيذ ، ومنطقة تعليمات التشغيل (تخزين تعليمات التشغيل) ؛
منطقة الطريقة (منطقة ثابتة):
1. مشترك من قبل جميع المواضيع. تحتوي منطقة الطريقة على جميع الفئات (تشير الفئة إلى الكود الأصلي للفئة. لإنشاء كائن فئة ، يجب تحميل رمز الفئة في منطقة الطريقة وتهيئته) والمتغيرات الثابتة.
2. تحتوي منطقة الأسلوب على عناصر فريدة من نوعها دائمًا في البرنامج بأكمله ، مثل المتغيرات الفئة والستاتية.
2. مثال العرض التوضيحي
appmain.java
الفئة العامة APPMAIN // عند التشغيل ، يضع JVM جميع رمز APPMAIN في منطقة الطريقة {Public Static Void Main (String [] args) // يتم وضع الطريقة الرئيسية نفسها في منطقة الطريقة. {عينة test1 = عينة جديدة ("اختبار 1") ؛ . عينة test2 = عينة جديدة ("اختبار 2") ؛ test1.printName () ؛ test2.printName () ؛ }} عينة الفئة العامة // عند التشغيل ، يضع JVM جميع معلومات AppMain في منطقة الطريقة { /** اسم المثال* /اسم السلسلة الخاصة ؛ // بعد مثيل عينة جديد ، يتم وضع مرجع الاسم في منطقة المكدس ، ويتم وضع كائن السلسلة المقابل في مُنشئ الكومة/***/عينة عامة (اسم السلسلة) {this .name = name ؛ } /** الإخراج* /public void printname () // عندما لا يكون هناك كائن ، يتم وضع طريقة الطباعة في منطقة الطريقة جنبًا إلى جنب مع فئة العينة. {system.out.println (name) ؛ }}عند تشغيل البرنامج ، ابدأ أولاً عملية الجهاز الظاهري Java. تعثر هذه العملية أولاً على ملف appmain.class من ClassPath ، ويقرأ البيانات الثنائية في الملف ، ثم تخزن معلومات الفئة لفئة AppMain في منطقة طريقة بيانات وقت التشغيل. هذه هي عملية التحميل لفئة AppMain.
بعد ذلك ، يحدد جهاز Java Virtual جهاز Bytecode للطريقة الرئيسية () لفئة AppMain في منطقة الطريقة ويبدأ في تنفيذ تعليماته. البيان الأول لهذه الطريقة الرئيسية () هو:
نسخة الكود كما يلي:
عينة test1 = عينة جديدة ("test1") ؛
عملية تنفيذ هذا البيان:
1. وجد الجهاز الظاهري Java معلومات النوع لفئة العينة في منطقة الطريقة ، ولكن لم يتم العثور عليها ، لأن فئة العينة لم يتم تحميلها في منطقة الطريقة (يمكن ملاحظة هنا أن الطبقات الداخلية في Java موجودة بشكل منفصل ، وفي البداية ، لن يتم تحميلها مع فئة الاحتواء ، ولن يتم تحميلها حتى يتم استخدامها حتى يتم استخدامها). يقوم جهاز Java الظاهري بتحميل فئة العينة على الفور ويخزن معلومات نوع فئة العينة في منطقة الطريقة.
2. يخصص جهاز Java Virtual ذاكرة أولاً لمثيل عينة جديد في منطقة الكومة ، ويخزن عنوان ذاكرة في منطقة الطريقة التي يتم فيها تخزين معلومات نوع فئة العينة في ذاكرة مثيل العينة.
3. في عملية JVM ، سيكون لكل مؤشر ترابط مكدس استدعاء الطريقة ، والذي يتم استخدامه لتتبع سلسلة من عمليات استدعاء الطريقة أثناء تشغيل مؤشر الترابط. يسمى كل عنصر في المكدس إطار مكدس. عندما يتصل مؤشر ترابط بطريقة ما ، سيتم دفع إطار جديد إلى مكدس الطريقة. يتم استخدام الإطارات هنا لتخزين معلمات الطريقة والمتغيرات المحلية والبيانات المؤقتة أثناء العملية.
4. Test1 قبل "=" هو متغير (مرجع إلى كائن عينة) محدد في الطريقة الرئيسية () ، لذلك سيتم إضافته إلى مكدس استدعاء طريقة Java من مؤشر الترابط الرئيسي الذي ينفذ الطريقة الرئيسية (). و "=" سوف يشير هذا المتغير test1 إلى مثيل العينة في منطقة الكومة.
5. يستمر JVM في إنشاء مثيل عينة آخر في منطقة الكومة ، ويضيف متغير Test2 إلى كومة استدعاء الطريقة للطريقة الرئيسية ، والتي تشير إلى مثيل العينة الجديد الذي تم إنشاؤه للتو في منطقة الكومة.
6. ينفذ JVM طريقة printname () بدوره. عندما ينفذ جهاز Java Virtual طريقة Test1.PrintName () ، يحدد جهاز Java Virtual مثيل العينة في منطقة الكومة استنادًا إلى المرجع الذي يحتفظ به اختبار المتغير المحلي ، ثم يحدد موقع معلومات نوع فئة العينة في الطريقة بناءً على المرجع الذي تم تنفيذه بواسطة مثيل العينة ، وبالتالي الحصول على ترتيب bytecode لأسماء الطباعة () ثم تنفيذ الإرشادات التي تتضمنها.
ثالثا. يميز
الفرق بين الكومة والمكدس في لغة جافا:
1. المكدس والكوتين كلا المكانين تستخدمهما Java لتخزين البيانات في ذاكرة الوصول العشوائي. على عكس C ++ ، تدير Java تلقائيًا الكدسات والأكوام ، ولا يمكن للمبرمجين إعداد أكوام أو أكوام مباشرة.
2. ميزة المكدس هي أن سرعة الوصول أسرع من الكومة ، والثانية فقط إلى السجلات الموجودة مباشرة في وحدة المعالجة المركزية. لكن العيب هو أن حجم البيانات وعمره في المكدس يجب أن يكون حتميًا ويفتقر إلى المرونة. بالإضافة إلى ذلك ، يمكن مشاركة بيانات المكدس (انظر المقدمة أدناه للحصول على التفاصيل). تتمثل ميزة الكومة في أنه يمكن تخصيص حجم الذاكرة ديناميكيًا ، ولا يجب إخبار المترجم مقدمًا مقدمًا. سيقوم جامع القمامة من Java تلقائيًا بجمع البيانات التي لم تعد تستخدم. ولكن العيب هو أنه يجب تخصيص الذاكرة ديناميكيًا في وقت التشغيل ، فإن سرعة الوصول أبطأ.
2 أنواع البيانات في جافا:
الأول هو الأنواع البدائية ، مع 8 فئات ، وهي int ، قصيرة ، طويلة ، بايت ، تعويم ، مزدوج ، منطقية ، شار (لاحظ أنه لا يوجد نوع أساسي من السلسلة). يتم تعريف هذا النوع من التعريف بواسطة نموذج مثل int a = 3 ؛ طويل ب = 255L ؛ ويسمى متغير تلقائي. المتغيرات التلقائية لها قيم حرفية ، وليس مثيلات من الفصول ، أي أنها ليست إشارات إلى الفصول ، ولا يوجد فصل هنا. على سبيل المثال ، int a = 3 ؛ هنا A عبارة عن مرجع يشير إلى نوع int ، مشيرًا إلى القيمة الحرفية لل 3. نظرًا لحجم هذه البيانات الحرفية وعمرها ، يتم تحديد هذه القيم الحرفية بشكل ثابت في كتلة البرنامج ، وتختفي قيمة الحقل بعد خروج كتلة البرنامج) ، وهي موجودة في المكدس من أجل متابعة السرعة.
يحتوي المكدس على ميزة مهمة للغاية: يمكن مشاركة البيانات الموجودة في المكدس. لنفترض أننا نحدد في نفس الوقت: int a = 3 ؛ int b = 3 ؛ المعالجة المترجم أولاً int a = 3 ؛ أولاً ، سيقوم بإنشاء مرجع مع متغير A في المكدس ، ثم اكتشف ما إذا كان هناك عنوان ذي قيمة حرفية تبلغ 3. إذا لم يتم العثور عليه ، فسيفتح عنوانًا ذو قيمة حرفية 3 ، ثم قم بإشارة A إلى عنوان 3. ثم معالجة int B = 3 ؛ بعد إنشاء المتغير المرجعي لـ B ، نظرًا لوجود قيمة حرفية بالفعل 3 في المكدس ، يُشار بشكل مباشر إلى عنوان 3. وبهذه الطريقة ، يشير كلا و B إلى 3 في نفس الوقت.
تختلف هذه الإشارة إلى القيم الحرفية عن كائنات الفئة. على افتراض أن مراجع كائنين من الفئة تشير إلى كائن في نفس الوقت ، إذا قام متغير مرجع كائن واحد بتغيير الحالة الداخلية للكائن ، فإن متغير مرجع الكائن الآخر يعكس هذا التغيير على الفور. بدلاً من ذلك ، لن يتسبب تعديل قيمته من خلال مرجع حرفي في تغيير قيمة أخرى وفقًا لذلك. كما في المثال أعلاه ، بعد تحديد قيم A و B ، دع A = 4 ؛ بعد ذلك ، لن تكون B مساوية لـ 4 ، أو تساوي 3. داخل المترجم ، عند مواجهة A = 4 ، ستعيد البحث عما إذا كانت هناك قيمة حرفية تبلغ 4 في المكدس. إذا لم يكن الأمر كذلك ، أعد فتح العنوان لتخزين قيمة 4 ؛ إذا كان موجودًا بالفعل ، فقم مباشرة بتوضيح A إلى هذا العنوان. لذلك ، لن يؤثر التغيير في القيمة A على القيمة ب.
نوع آخر هو بيانات فئة التغليف ، مثل عدد صحيح ، سلسلة ، مزدوجة ، وما إلى ذلك التي تلتف أنواع البيانات الأساسية المقابلة. كل هذه البيانات الفئة موجودة في الكومة. تستخدم Java عبارة جديدة () لعرض المترجم ويقوم فقط بإنشاء ديناميكي فقط حسب الحاجة في وقت التشغيل ، لذلك يكون أكثر مرونة ، ولكن العيب هو أنه يستغرق المزيد من الوقت.
4. ملخص
لا يزال بنية تخصيص ذاكرة Java واضحة للغاية. إذا كنت تريد أن تفهمها تمامًا ، فيمكنك التحقق من الكتب المتعلقة بـ JVM. في Java ، الشيء الأكثر إثارة للقلق حول تخصيص الذاكرة هو كائن السلسلة. بسبب طبيعتها الخاصة ، فإن العديد من المبرمجين عرضة للارتباك. سأشرح ذلك بالتفصيل في المقالة التالية.