إدارة الذاكرة في Java
⚡ ملخص ذكي
إدارة الذاكرة في Java يشرح كيف تقسم آلة جافا الافتراضية ذاكرة وقت التشغيل عبر المكدس والكومة Codeوالمناطق الثابتة، وكيفية تدفق مراجع الكائنات أثناء استدعاءات الأساليب، وكيف يقوم جامع البيانات المهملة باستعادة الكائنات التي لا يمكن الوصول إليها حتى تظل التطبيقات مستقرة وخالية من تسرب الذاكرة.

ما هي ذاكرة المكدس في Java?
ذاكرة المكدس في Java تُعدّ Stack منطقة في ذاكرة JVM تُخزّن إطارات الدوال والمتغيرات المحلية ومتغيرات المراجع لكل خيط. ويتم الوصول إلى Stack دائمًا بترتيب Last-In-First-Out، بحيث تكون الدالة التي تم استدعاؤها مؤخرًا في الأعلى، ويتم دفع متغيراتها المحلية وسحبها مع الإطار.
كل خيط في Java تتلقى الآلة الافتراضية مكدسها الخاص، الذي يحافظ على عزل استدعاءات الأساليب وأمانها في بيئة متعددة الخيوط. توجد المتغيرات المحلية الأولية مثل int و boolean و double مباشرةً داخل الإطار، بينما تشير مراجع الكائنات المخزنة على المكدس إلى الكائنات المخصصة في الذاكرة الديناميكية (Heap).
ما هي ذاكرة الكومة في Java?
ذاكرة الكومة هي منطقة JVM المشتركة التي تحتوي على كل Java يتم إنشاء الكائن والمصفوفة باستخدام عامل التشغيل new، بالإضافة إلى أي متغيرات مرجعية تابعة لتلك الكائنات كحقول مثيل. على عكس المكدس، تتم مشاركة الكومة عبر جميع الخيوط، ولهذا السبب غالبًا ما يتطلب الوصول إلى الكائنات مزامنة.
الكومة هي المنطقة التي يديرها جامع البيانات المهملة. تقسم آلات جافا الافتراضية الحديثة HotSpot الكومة إلى جيل صغير للكائنات قصيرة العمر وجيل قديم للكائنات طويلة العمر، مع تخزين بيانات تعريف الفئة في منطقة أصلية منفصلة تسمى ميتا سبيس.
تخصيص الذاكرة في Java
تخصيص الذاكرة في Java هي العملية التي تقوم بها آلة جافا الافتراضية (JVM) بتخصيص مناطق ذاكرة افتراضية للمتغيرات ونسخ الفئات والهياكل أثناء تنفيذ البرنامج. لا يتم تخصيص الذاكرة للكائن عند تعريفه، بل يتم إنشاء مرجع فقط. يتم تخصيص الكائن فعليًا من خلال عامل التشغيل new، لذا فإن كل كائن موجود في الذاكرة الديناميكية (Heap).
استخدم Java ينقسم تخصيص الذاكرة إلى الأقسام التالية:
- كومة
- كومة
- Code
- ساكن
يُعد تقسيم الذاكرة هذا ضرورياً للإدارة الفعالة لوقت التشغيل.
- استخدم Code يحتوي هذا القسم على ما قمت بتجميعه بايت كود.
- استخدم كومة متاجر الأقسام الأساليب، والمتغيرات المحلية، والمتغيرات المرجعية.
- استخدم كومة يحتوي القسم الأجسام وقد تحتوي أيضًا على متغيرات مرجعية محفوظة كحقول مثيل.
- استخدم ساكن القسم يحتوي البيانات الثابتة والأساليب الثابتة يتم مشاركتها عبر جميع الحالات.
الفرق بين المتغير المحلي ومتغير المثيل
يساعد فهم مكان وجود كل نوع من أنواع المتغيرات في JVM على شرح سلوك المكدس والكومة. المتغيرات الخاصة أعلن داخل فئة ولكن خارج أي دالةوهو موجود في الكومة كجزء من كائنه.
class Student{ int num; // num is instance variable public void showData{}
A متغير محلي أعلن داخل دالة، بما في ذلك وسائط الدالة، وتعيش على المكدس داخل الإطار النشط.
public void sum(int a){ int x = a + 3; // a, x are local variables }
الفرق بين المكدس والكومة
يُعالج كلٌّ من المكدس والكومة مشكلاتٍ مختلفة داخل آلة جافا الافتراضية. يُتيح المكدس لكل خيط تخصيصًا سريعًا ومحددًا للبيانات قصيرة الأجل المرتبطة بنطاق الدالة، بينما تُوفّر الكومة منطقةً مشتركةً للكائنات طويلة الأجل التي يُمكن لأي خيط الرجوع إليها. يُلخّص الفيديو القصير أدناه الفرق بينهما قبل الشرح العملي الذي يليه.
انقر اضغط هنا إذا لم يكن من الممكن الوصول إلى الفيديو
لمعرفة كيفية تعاون المكدس والكومة، ضع في اعتبارك طريقة رئيسية تستدعي الطريقة m1.
public void m1{ int x = 20; }
في مكدس JVM، يتم إنشاء إطار للطريقة m1.
يتم أيضًا إنشاء المتغير x في m1 في إطار m1 على المكدس، كما هو موضح في الصورة أدناه.
ثم يقوم الأسلوب m1 باستدعاء الأسلوب m2. في المكدس، يتم إنشاء إطار جديد لـ m2 فوق إطار m1.
يتم أيضًا إنشاء المتغيرات المحلية b و c داخل إطار m2 على المكدس.
public void m2(int b){ boolean c; }
بعد ذلك، يستدعي m2 الطريقة m3. ومرة أخرى، يتم إنشاء إطار لـ m3 في أعلى المكدس، كما هو موضح أدناه.
لنفترض الآن أن الدالة m3 تنشئ كائنًا من فئة Account، والذي يحتوي على اثنين متغيرات سريعة إنت ص و إنت ف.
class Account { int p; int q; }
إليكم رمز الطريقة m3.
public void m3(){ Account ref = new Account(); // more code }
تقوم العبارة new Account() بإنشاء كائن من نوع Account في الذاكرة الديناميكية (Heap).
يتم إنشاء متغير المرجع ref على المكدس داخل الإطار الخاص بـ m3.
يجعل عامل التعيين متغير المرجع يشير إلى الكائن الموجود في الذاكرة الديناميكية (Heap).
بمجرد اكتمال تنفيذ الطريقة، يعود التحكم إلى الطريقة المستدعِية، وهي في هذه الحالة الطريقة m2.
يتم إخراج إطار الطريقة m3 من المكدس.
بما أن المتغير المرجعي لم يعد يشير إلى الكائن الموجود في الذاكرة الرئيسية، فإن هذا الكائن يصبح مؤهلاً لجمع البيانات المهملة.
بمجرد انتهاء تنفيذ الدالة m2، يتم إزالتها من مكدس الاستدعاءات وتصبح جميع متغيراتها غير متاحة. ويحدث الشيء نفسه مع الدالة m1، وفي النهاية يعود التحكم إلى الدالة الرئيسية.
ماذا لو كان الكائن يحتوي على مرجع آخر كمتغير مثيل له؟
public static void main(String args[]) { A parent = new A(); // more code } class A { B child = new B(); int e; } class B { int c; int d; }
في هذه الحالة، يوجد المتغير المرجعي child في الذاكرة كجزء من الكائن A، ويشير بدوره إلى الكائن B الخاص به، كما هو موضح أدناه.
ما هو جمع القمامة في Java?
جمع القمامة في Java هي العملية التي تُدير بها آلة جافا الافتراضية (JVM) الذاكرة تلقائيًا. يقوم جامع البيانات المهملة (Garbage Collector) بالعثور على الكائنات التي لم تعد قابلة للوصول إليها من أي مرجع نشط، ثم يستعيد ذاكرتها. يتم تخصيص الذاكرة الديناميكية من خلال عامل التشغيل new، وتبقى الذاكرة مُخصصة حتى يتوقف البرنامج عن الاحتفاظ بأي مرجع للكائن.
عندما لا تبقى أي مراجع، يُعتبر الكائن غير مطلوب، ويمكن استعادة الذاكرة التي يشغلها. لا توجد حاجة صريحة لتدمير الكائن لأن Java يتولى جامع البيانات المهملة عملية إلغاء التخصيص تلقائيًا.
تُعرف التقنية الكامنة وراء ذلك باسم جمع القمامةالبرامج التي تفشل في تحرير الذاكرة تتعطل في النهاية عندما لا يتبقى شيء لتخصيصه. ويُقال إن هذه البرامج تعاني من خلل في الذاكرة. تسريبات الذاكرة. جمع القمامة في Java يتم تشغيله تلقائيًا طوال فترة البرنامج، مما يزيل عبء إلغاء التخصيص اليدوي ويقلل من خطر التسريبات.
في لغة C، على النقيض من ذلك، يكون المبرمج مسؤولاً عن تحرير الذاكرة المخصصة ديناميكيًا من خلال الدالة free(). هذا هو المكان الذي Java توفر إدارة الذاكرة ميزة قوية.
تُوفر بيئات JVM الحديثة لتقنية HotSpot عدة مُجمّعات قمامة مُحسّنة لأحمال عمل مُختلفة. يستهدف مُجمّع القمامة الافتراضي G1 تحقيق توازن بين الإنتاجية وأوقات التوقف المؤقت على أكوام الذاكرة الضخمة (عدة غيغابايت). بينما يهدف كل من ZGC و Shenandoah إلى تحقيق توقفات مؤقتة في أقل من جزء من الألف من الثانية على أكوام الذاكرة الضخمة جدًا، مما يجعلهما فيtracيُعد اختيار المُجمِّع المناسب وضبط أحجام الجيل الصغير والجيل القديم ومساحة التخزين مهارة أساسية للخدمات الحساسة للتأخير. Java عمل أدائي.
ملاحظة: يتم إنشاء جميع الكائنات في قسم الكومة من الذاكرة، وهي المنطقة التي يديرها جامع البيانات المهملة.
مثال: للتعرف على آلية تجميع البيانات المهملة في Java
يوضح هذا الدليل متى تصبح المراجع مؤهلة لجمع البيانات المهملة داخل برنامج بسيط.
الخطوة 1) انسخ الكود التالي إلى المحرر.
class Student{ int a; int b; public void setData(int c,int d){ a=c; b=d; } public void showData(){ System.out.println("Value of a = "+a); System.out.println("Value of b = "+b); } public static void main(String args[]){ Student s1 = new Student(); Student s2 = new Student(); s1.setData(1,2); s2.setData(3,4); s1.showData(); s2.showData(); //Student s3; //s3=s2; //s3.showData(); //s2=null; //s3.showData(); //s3=null; //s3.showData(); } }
الخطوة 2) احفظ الكود وقم بتجميعه وتشغيله. كما هو موضح في الرسم التخطيطي، يتم إنشاء كائنين ومتغيرين مرجعيين.
الخطوة 3) قم بإلغاء التعليق على الأسطر 20 و 21 و 22. احفظ الكود وقم بتجميعه وتشغيله.
الخطوة 4) كما هو موضح في الرسم البياني أدناه، يشير متغيران مرجعيان الآن إلى نفس الكائن.
الخطوة 5) قم بإلغاء التعليق على السطرين 23 و 24. احفظ الكود وقم بتجميعه وتشغيله.
الخطوة 6) كما هو موضح أدناه، يصبح s2 فارغًا، لكن s3 لا يزال يشير إلى الكائن، لذلك فإن الكائن ليس مؤهلًا بعد لجمع البيانات المهملة.
الخطوة 7) قم بإلغاء التعليق على السطرين 25 و 26. احفظ الكود وقم بتجميعه وتشغيله.
الخطوة 8) في هذه المرحلة، لا توجد أي مراجع تشير إلى الكائن، لذا يصبح مؤهلاً لعملية جمع البيانات المهملة. يقوم جامع البيانات المهملة بإزالته من الذاكرة، ولا توجد طريقة لاستعادته.
كيفية حذف عنصر في Java?
Java لا يوفر عامل حذف يدوي، لذا فإن النهج القياسي هو إزالة كل مرجع للكائن حتى يتمكن جامع البيانات المهملة من استعادته.
1) لجعل كائن ما مؤهلاً لجمع البيانات المهملة، قم بتعيين كل متغير مرجعي يشير إليه إلى قيمة فارغة (null).
2) الأنواع الأولية ليست كائنات، لذا لا يمكن إسناد قيمة فارغة لها. يتم استعادة مساحة التخزين الخاصة بها تلقائيًا عند إزالة إطار المكدس المحيط بها.


















