يعد Java Virtual Machine (JVM) مكونًا مهمًا في بيئة Java runtime ، وهو مسؤول عن تنفيذ برامج Java bytecode. يوفر بيئة برمجية متسقة مستقلة عن النظام الأساسي تمكن تطبيقات Java من العمل بسلاسة على مختلف بنى الأجهزة وأنظمة التشغيل ، وهي ميزة رئيسية لـ JVM.
عادةً ما تتم كتابة تطبيقات Java بلغة برمجة Java ، ويتم تجميعها في تنسيق bytecode (ملفات * .class) ، ثم يتم تحميلها وتنفيذها بواسطة JVM. يقوم JVM بترجمة الرمز الثانوي إلى رمز جهاز أصلي خاص بنظام التشغيل والأجهزة الأساسية ، مما يسمح لتطبيقات Java بالعمل على أنظمة أساسية متعددة دون تعديل. غالبًا ما يُشار إلى هذه العملية بمبدأ "الكتابة مرة واحدة ، والتشغيل في أي مكان".
علاوة على ذلك ، يعتني JVM بإدارة الذاكرة وجمع البيانات المهملة وتحسين وقت التشغيل ، مما يجعله مكونًا أساسيًا للتنفيذ الفعال لبرامج Java.
مكونات JVM ووظائفها
تتكون بنية JVM من عدة مكونات تعمل معًا لإدارة دورة حياة تطبيقات Java. تشمل هذه المكونات:
- Classloader: Classloader مسؤول عن تحميل فئات Java من القرص إلى ذاكرة JVM ، وحل تبعيات الفئة ، وتهيئة الفئات أثناء تشغيل البرنامج. يتبع Classloader التسلسل الهرمي للتفويض ، بدءًا من Bootstrap Classloader ، متبوعًا بـ Extension Classloader ، و Application Classloader.
- مناطق بيانات وقت التشغيل: يخصص JVM مساحات ذاكرة تسمى مناطق بيانات وقت التشغيل أثناء تنفيذ البرنامج. تتضمن مساحات الذاكرة هذه Heap و Stack و Method Area و Constant Pool و PC Registers ، والتي تخزن البيانات المطلوبة لجوانب مختلفة من دورة حياة التطبيق.
- محرك التنفيذ: محرك التنفيذ هو المكون الأساسي المسؤول عن تنفيذ Java bytecode. يفسر محرك التنفيذ رمز بايت ويحوله إلى رمز جهاز أصلي أثناء وقت التشغيل. يتضمن مكونات مثل المترجم الفوري ومترجم Just-In-Time (JIT) ومجمع القمامة.
في الأقسام التالية ، سنتعمق في تفاصيل إدارة ذاكرة JVM ومساحات الذاكرة المختلفة التي تشكل بنية JVM.
إدارة ذاكرة JVM
تعد الإدارة الفعالة للذاكرة جانبًا أساسيًا من بنية JVM التي تساهم في التنفيذ الفعال لتطبيقات Java. يخصص JVM مساحات ذاكرة مختلفة ، تسمى مناطق بيانات وقت التشغيل ، للتعامل مع أنواع مختلفة من تخزين البيانات ومعالجتها أثناء تنفيذ البرنامج. تشمل مناطق الذاكرة الرئيسية في JVM ما يلي:
- الكومة: الكومة هي أكبر مساحة ذاكرة في JVM وتتم مشاركتها بين جميع سلاسل العمليات في التطبيق. يخزن الكائنات والمصفوفات التي تم إنشاؤها أثناء تنفيذ البرنامج. وتنقسم الكومة أيضًا إلى مناطق "جيل الشباب" و "الجيل القديم". تخزن منطقة جيل الشباب الكائنات التي تم إنشاؤها حديثًا ، بينما تحتوي منطقة الجيل القديم على كائنات نجت من دورات جمع القمامة المتعددة.
- المكدس: يُنشئ JVM مكدسًا منفصلاً لكل مؤشر ترابط. تقوم Stacks بتخزين معلومات استدعاء الطريقة والمتغيرات المحلية والنتائج الوسيطة للحسابات أثناء تنفيذ البرنامج. يُطلق على كل إدخال في المكدس اسم Stack Frame ، ويدير JVM إطارات Stack Frames بشكل مستقل لكل استدعاء طريقة.
- منطقة الطريقة: يتم مشاركة منطقة الطريقة بين جميع سلاسل العمليات في التطبيق وتخزين بيانات الفئة ، مثل أسماء الطرق وأسماء المتغيرات والقيم الثابتة. تحتوي منطقة الطريقة أيضًا على مجموعة ثابتة ، والتي تحتوي على قيم ثابتة ومراجع رمزية يستخدمها الرمز الثانوي.
- تسجيلات الكمبيوتر الشخصي: سجل جهاز الكمبيوتر (عداد البرامج) هو منطقة ذاكرة تحتوي على عنوان تعليمات JVM المنفذة حاليًا لكل مؤشر ترابط. يساعد سجل الكمبيوتر الشخصي JVM على تتبع التعليمات التي يجب تنفيذها بعد ذلك.
بصرف النظر عن مناطق الذاكرة هذه ، تستخدم JVM أيضًا أداة تجميع القمامة ، والتي تقوم تلقائيًا بإلغاء تخصيص الذاكرة للكائنات التي لم تعد مطلوبة ، وبالتالي تقليل تسرب الذاكرة وتحسين استخدام الموارد.
باختصار ، تحتوي بنية JVM على نظام إدارة ذاكرة محدد جيدًا يعمل على تحسين تنفيذ تطبيقات Java ويضمن الاستخدام الفعال للموارد. يتيح فهم مكونات JVM ووظائفها للمطورين إنشاء تطبيقات Java وتحسينها للحصول على أفضل أداء ممكن.
محمل فئة JVM
يعد Classloader مكونًا حيويًا في Java Virtual Machine (JVM) الذي يقوم بتحميل فئات Java في ذاكرة JVM. وهي مسؤولة عن ثلاثة أنشطة أساسية: التحميل والربط والتهيئة. دعنا نستكشف هذه الأنشطة بالتفصيل.
تحميل
التحميل هو عملية جلب ملفات الفئة من القرص وتحميلها في ذاكرة JVM. يحدد Classloader موقع ملفات الفئة المطلوبة باستخدام اسم الفئة المؤهل بالكامل ، والذي يتضمن اسم الحزمة واسم الفئة. توجد ثلاثة أنواع من محمل الفصل في JVM:
- Bootstrap Classloader: هذا هو أداة تحميل Classloader المدمجة في JVM ويقوم بتحميل فئات Java الأساسية ، مثل
java.lang.Object
وفئات وقت التشغيل الأخرى من ملفrt.jar
. - ملحق Classloader: هذا Classloader مسؤول عن تحميل الفئات من دليل
ext
الخاص بـ JDK ، والذي يحتوي على مكتبات Java وأطر عمل إضافية. - محمل فئة النظام / التطبيق: يُحمّل Classloader الافتراضي الفئات من مسار فئة التطبيق. يمكن تحديد classpath باستخدام الخيارين
-cp
أو-classpath
عند تنفيذ تطبيق Java.
يتبع Classloader التسلسل الهرمي للتفويض ، بدءًا من Bootstrap Classloader والانتقال إلى الملحق ومحمل فئة النظام / التطبيق.
مصدر الصورة: شبكة جافا التعليمية
ربط
تقوم عملية الربط بإنشاء اتصالات الفئة والتحقق من التناقضات أو الأخطاء. يتكون الربط من ثلاث خطوات:
- التحقق: خلال هذه الخطوة ، يضمن JVM أن ملفات الفئة المحملة تلتزم بالبنية والقيود المحددة في مواصفات لغة Java. سيتم رفض أي ملفات فئة مشوهة أو ضارة في هذه المرحلة.
- التحضير: يقوم JVM بتهيئة الحقول والأساليب الثابتة والموارد الأخرى اللازمة لتنفيذ الفصل. يقوم بتعيين القيم الافتراضية للحقول الثابتة وتخصيص الذاكرة لها.
- الحل: تعمل هذه الخطوة على حل المراجع الرمزية في ملفات الفئة عن طريق استبدالها بمراجع مباشرة ، مثل عناوين الأسلوب وإزاحات الحقول. يتم تنفيذ هذه العملية ديناميكيًا في وقت التشغيل.
التهيئة
التهيئة هي الخطوة الأخيرة في عملية أداة تحميل الفصل. أثناء هذه المرحلة ، يقوم JVM بتشغيل أي كتل تعليمات برمجية ثابتة في الفئة وتعيين القيم الأولية المحددة في ملف الفئة إلى الحقول الثابتة. كما أنه يضمن حدوث التهيئة الثابتة مرة واحدة فقط ، حتى في البيئات متعددة مؤشرات الترابط.
مترجم JIT وجامع القمامة
يعد برنامج التحويل البرمجي Just-In-Time (JIT) ومجمع القمامة مكونات JVM الأساسية التي تعمل على تحسين أداء التطبيق بشكل كبير وإدارة موارد النظام.
مترجم JIT
مترجم Just-In-Time (JIT) مسؤول عن تحويل Java bytecode إلى كود الجهاز الأصلي في وقت التشغيل. تعمل هذه العملية على تحسين سرعة تنفيذ تطبيقات Java. يقوم مترجم JIT بتجميع طرق تسمى بشكل متكرر ، ويخزن الكود المترجم مؤقتًا ، ويعيد استخدامه في عمليات التنفيذ المستقبلية ، مما يقلل من عبء تفسير الرمز الثانوي بشكل متكرر.
يستخدم JVM طريقة "اكتشاف النقاط الفعالة" لتحديد الأساليب التي يتم تسميتها بشكل متكرر. بمجرد الوصول إلى عتبة نقطة الاتصال ، يبدأ مترجم JIT ويجمع الرمز الثانوي في رمز الجهاز الأصلي. تقوم وحدة المعالجة المركزية بتنفيذ هذا الرمز المترجم مباشرة ، مما يؤدي إلى أوقات تنفيذ أسرع بشكل ملحوظ.
جامع القمامة
مجمع القمامة (GC) هو مكون JVM أساسي مسؤول عن أتمتة إدارة الذاكرة. يقوم بإلغاء تخصيص الذاكرة من الكائنات التي لم يعد التطبيق يحتاجها أو يشير إليها. تقلل هذه العملية من تسرب الذاكرة وتحسن استخدام الموارد في تطبيقات Java. يستخدم JVM استراتيجية جمع القمامة للأجيال ، وتقسيم ذاكرة الكومة إلى الأجيال الشابة والشيخوخة. ينقسم جيل الشباب أيضًا إلى عدن سبيس ، ونافورة سبيس 0 (س 0) ، وسيرفايفر سبيس 1 (س 1).
الفكرة الأساسية وراء جمع القمامة عبر الأجيال هي أن معظم الكائنات لها عمر قصير ومن المحتمل أن يتم جمعها للقمامة بعد وقت قصير من إنشائها. ومن ثم ، فإن تخصيص الذاكرة وإلغاء تخصيصها بشكل متكرر في جيل الشباب يؤدي إلى تحسين عملية جمع البيانات المهملة. يقوم Garbage Collector بتنظيف الكائنات غير المستخدمة في ذاكرة الكومة باستخدام خوارزميات مختلفة مثل Mark-Sweep-Compact و Copy و Generational Collection.
مناطق بيانات وقت تشغيل JVM
مناطق بيانات وقت تشغيل JVM هي مساحات ذاكرة مخصصة بواسطة JVM لتخزين البيانات أثناء تنفيذ البرنامج. تعد مناطق البيانات هذه ضرورية لإدارة الموارد وتسهيل التنفيذ الفعال لتطبيقات Java. تتضمن مناطق بيانات وقت التشغيل الرئيسية في JVM كومة ، ومكدس ، ومنطقة الطريقة ، وتجمع ثابت ، وسجلات الكمبيوتر.
كومة
الكومة هي منطقة ذاكرة مشتركة في JVM تخزن الكائنات ومتغيرات الحالة. إنها أكبر مساحة للذاكرة وتنقسم إلى أجيال لجمع القمامة بكفاءة ، كما هو موضح في قسم Garbage Collector. نظرًا لأنه يمكن الوصول إلى الكائنات الموجودة في الكومة بشكل عام ، فإن آليات مزامنة مؤشر الترابط مطلوبة لتجنب مشاكل عدم تناسق البيانات في التطبيقات متعددة مؤشرات الترابط.
كومة
المكدس هو منطقة ذاكرة تخزن المتغيرات المحلية ومعلومات استدعاء الطريقة. يحتوي كل مؤشر ترابط في JVM على مكدس ، ولا يمكن الوصول إلى البيانات المخزنة في المكدس إلا ضمن نطاق مؤشر الترابط المقابل. ونتيجة لذلك ، فإن مزامنة مؤشر الترابط غير مطلوبة للوصول إلى ذاكرة المكدس. يسهل المكدس طريقة Last-In-First-Out (LIFO) لتخزين البيانات واستردادها ، مما يجعلها فعالة لإدارة تنفيذ استدعاء الطريقة.
منطقة الطريقة
منطقة الطريقة هي مساحة ذاكرة مشتركة تخزن بيانات التعريف ومعلومات التجمع الثابت والحقول الثابتة لكل فئة محملة. هذا المجال ضروري لإدارة المعلومات المتعلقة بالفصل الدراسي وتوفير البيانات اللازمة للربط الديناميكي وتنفيذ الرمز الثانوي.
تجمع ثابت
The Constant Pool هو بنية بيانات في منطقة الطريقة تخزن الثوابت ، مثل سلسلة الأحرف وأسماء الفئات وأسماء الطرق المشار إليها بواسطة Java bytecode. يعمل كمستودع مركزي لجميع القيم الثابتة ويساعد في حل المراجع الرمزية أثناء عملية الربط.
تسجيلات الكمبيوتر
Program Counter (PC) Register هو منطقة ذاكرة تخزن عنوان تعليمات Java bytecode التي يتم تنفيذها حاليًا لكل مؤشر ترابط. يساعد سجل الكمبيوتر في إدارة تنفيذ مؤشر الترابط والحفاظ على تسلسل تنفيذ التعليمات في JVM. يحتوي على عنوان الذاكرة لتعليمات الرمز الثانوي التالية التي سيتم تنفيذها ، ويتم تحديث قيمتها وفقًا لذلك حيث يعالج JVM تعليمات Java bytecode.
فوائد وقيود هندسة JVM
توفر بنية Java Virtual Machine (JVM) مزايا عديدة ، مما يجعلها خيارًا شائعًا للمطورين. ومع ذلك ، لا يوجد نظام بلا حدود. يقدم هذا القسم نظرة عامة على مزايا وعيوب هندسة JVM.
فوائد هندسة JVM
- استقلالية النظام الأساسي: أحد أهم مزايا JVM هو استقلالية النظام الأساسي. بفضل JVM ، يمكن تشغيل تطبيقات Java على منصات مختلفة دون الحاجة إلى أي تعديلات في التعليمات البرمجية. يقوم JVM بترجمة Java bytecode إلى كود آلة أصلي خاص بالنظام الأساسي الأساسي ، مما يضمن التنفيذ السلس عبر الأجهزة وأنظمة التشغيل المختلفة.
- قابلية التوسع: تم تصميم JVM للتعامل مع التطبيقات واسعة النطاق بكفاءة ، وذلك بفضل إمكانيات تعدد مؤشرات الترابط وميزات إدارة الذاكرة. تسمح هذه الخصائص للمطورين بإنشاء وصيانة التطبيقات التي يمكن أن تخدم العديد من المستخدمين دون المساس بالأداء.
- إدارة الذاكرة: يتيح نظام إدارة الذاكرة في JVM الاستخدام الأمثل لموارد النظام. يدير الذاكرة من خلال مناطق ذاكرة مختلفة (كومة ، ومكدس ، ومنطقة الطريقة ، وتسجيل الكمبيوتر الشخصي) ويوفر مجموعة القمامة لاستعادة الذاكرة المشغولة تلقائيًا بواسطة الكائنات التي لم تعد هناك حاجة إليها ، مما يقلل من تسرب الذاكرة ويحسن أداء التطبيق.
- تنفيذ Bytecode المحسن: يستخدم JVM تجميع Just-In-Time (JIT) لتحسين تنفيذ Java bytecode. يقوم مترجم JIT بترجمة الرمز الثانوي إلى رمز الجهاز الأصلي أثناء وقت التشغيل ، مما يؤدي إلى تحسين سرعة التنفيذ الإجمالية لتطبيقات Java عن طريق تجميع الأساليب التي يُطلق عليها بشكل متكرر وتخزين الشفرة المجمعة مؤقتًا للاستخدام في المستقبل.
- جمع القمامة: تقوم مجموعة القمامة الآلية الخاصة بـ JVM بإدارة الذاكرة بكفاءة عن طريق إلغاء تخصيص مساحات الذاكرة التي تشغلها كائنات غير مستخدمة. تعمل ميزة جمع البيانات المهملة على تحسين أداء تطبيقات Java وتبسيط مهام إدارة الذاكرة للمطورين.
حدود هندسة JVM
- النفقات العامة للأداء: تقدم JVM بعض النفقات العامة للأداء بسبب عمليات التفسير والتجميع. يمكن أن يؤدي تفسير الرمز الثانوي وتحويله إلى رمز الجهاز الأصلي أثناء وقت التشغيل إلى تنفيذ أبطأ من التطبيقات المكتوبة بلغات يتم تجميعها مباشرة إلى رمز الجهاز.
- استخدام الذاكرة: تستهلك مكونات JVM المختلفة ، مثل محمل الفصل ومحرك التنفيذ ومناطق بيانات وقت التشغيل ، ذاكرة النظام. قد يؤثر استخدام الذاكرة المتزايد هذا على التطبيقات التي تعمل على أجهزة محدودة الموارد ، مما يؤدي إلى انخفاض الأداء.
- فواق جمع القمامة: تقدم ميزة جمع القمامة في JVM العديد من الفوائد ولكنها يمكن أن تسبب أيضًا فواق في الأداء إذا لم يتم تحسينها بشكل صحيح. على سبيل المثال ، قد توقف أداة تجميع البيانات المهملة تنفيذ التطبيق مؤقتًا لأداء دورة تجميع بيانات مجمعة كاملة ، يشار إليها باسم التوقف المؤقت "stop-the-world". يمكن أن تؤثر فترات التوقف المؤقت هذه بشكل كبير على أداء التطبيق ، خاصة في سيناريوهات الإنتاجية العالية.
JVM و AppMaster.io: تعزيز التطوير No-code
AppMaster.io عبارة عن نظام أساسي قوي لا يحتوي على تعليمات برمجية مصمم لإنشاء تطبيقات الويب والجوال والخلفية بسرعة. تتيح المنصة للمستخدمين إنشاء نماذج البيانات ومنطق الأعمال وواجهات المستخدم بشكل مرئي باستخدام واجهة سحب وإفلات سهلة الاستخدام.
إنه يتعامل مع إنشاء التطبيقات وتصنيفها ونشرها عن طريق تجديد التطبيقات من نقطة الصفر كلما تغيرت المتطلبات ، وبالتالي القضاء على الديون التقنية. بفضل إمكانياته الواسعة ، يمكن أن يستفيد AppMaster.io أيضًا من بنية JVM بعدة طرق:
- الأدوات والمكتبات المستندة إلى Java: يمكن نشر النظام البيئي الشامل لـ JVM للأدوات والمكتبات المستندة إلى Java في التطبيقات التي تم إنشاؤها باستخدام AppMaster.io. يمكن أن يؤدي دمج مكتبات Java إلى تحسين قدرات التطبيقات بشكل كبير وتوفير وقت التطوير من خلال توفير حلول لمهام التطوير الشائعة.
- قابلية التوسع: يمكن الاستفادة من ميزات قابلية التوسع في JVM ، مثل تعدد مؤشرات الترابط وإدارة الذاكرة ، لإنشاء تطبيقات تتوسع بشكل فعال مع نمو قاعدة المستخدمين. يمكن أن يساعد AppMaster.io في إنشاء تطبيقات قابلة للتطوير بدرجة كبيرة عبر أنظمة تشغيل وأجهزة مختلفة من خلال دمج ميزات JVM.
- أداء مُحسَّن: يمكن لميزات التحسين الخاصة بـ JVM ، مثل تجميع Just-In-Time (JIT) وجمع البيانات المهملة آليًا ، تحسين أداء التطبيقات التي تم إنشاؤها بواسطة AppMaster.io. تساعد هذه التحسينات على زيادة استخدام موارد التطبيق إلى الحد الأقصى ، مما يسمح بتشغيل التطبيقات المبنية على AppMaster بشكل أسرع وأكثر كفاءة.
- إدارة الذاكرة: يمكن أن يستفيد AppMaster.io من إمكانيات إدارة ذاكرة JVM للاستفادة الفعالة من موارد النظام ، وتقليل تسرب الذاكرة وتحسين أداء التطبيقات.
في الختام ، مع ميزاتها وفوائدها المتنوعة ، يمكن لمعمارية JVM تحسين أداء وقدرات التطبيقات التي تم إنشاؤها باستخدام AppMaster.io. من خلال الاستفادة من ميزات النظام البيئي والتحسين الشامل لـ JVM ، يمكن أن يوفر AppMaster.io للمستخدمين أدوات تطوير no-code أكثر قوة وفعالية.