أهلاً! في الدرس الأخير، تعرفنا لأول مرة على أداة تجميع البيانات المهملة المدمجة في Java وحصلنا على فكرة تقريبية عن كيفية عملها. إنه يعمل في الخلفية أثناء تشغيل البرنامج، حيث يقوم بتجميع العناصر غير الضرورية التي سيتم حذفها لاحقًا. وبالتالي، فإنه يحرر الذاكرة التي يمكن استخدامها لإنشاء كائنات جديدة في المستقبل.
في هذا الدرس، سنناقش بمزيد من التفصيل كيفية عمله. على سبيل المثال، كيف ومتى يصبح الكائن غير ضروري؟ وكيف يعرف جامع القمامة ذلك؟ هذه أسئلة سنجيب عليها خلال درس اليوم :) سيكون الدرس أشبه بنظرة عامة: لست بحاجة إلى حفظ هذه المادة عن ظهر قلب. الهدف الأساسي هو توسيع رؤيتك فيما يتعلق بكيفية عمل الذاكرة وأداة تجميع البيانات المهملة، لذا اقرأ فقط وابحث عن شيء جديد لنفسك :) هيا بنا! أول شيء عليك أن تتذكره هو أن أداة تجميع البيانات المهملة تعمل بالتوازي مع برنامجك . انها ليست جزءا من البرنامج الخاص بك. تعمل بشكل منفصل (في الدرس الأخير، قمنا بمقارنة ذلك بالمكنسة الكهربائية الروبوتية) ولكن الأمر لم يكن كذلك دائمًا. كان يتم تنفيذ عملية جمع البيانات المهملة على نفس مؤشر ترابط برنامجك. في بعض الجداول الزمنية (مرة كل بضع دقائق)، يقوم جامع البيانات المهملة بالتحقق من وجود كائنات غير مرغوب فيها في البرنامج. كانت المشكلة أن البرنامج سوف يتعطل (لا يتم تنفيذه) أثناء هذا الفحص وجمع البيانات المهملة. تخيل أنك تجلس في مكتبك في العمل. ولكن بعد ذلك تأتي عاملة التنظيف لغسل الأرضيات. تقوم بإبعادك عن جهاز الكمبيوتر الخاص بك لمدة 5 دقائق وتنتظر حتى تنتهي من التنظيف. خلال هذا الوقت، لن تتمكن من العمل. يتعلق الأمر بكيفية عمل جمع البيانات المهملة :) تم تغيير هذه الآلية لاحقًا، والآن يعمل جامع البيانات المهملة في الخلفية، دون إعاقة عمل البرنامج نفسه. أنت تعلم بالفعل أن الكائن يموت عندما لا يكون له أي مراجع. في الواقع، لا يقوم جامع البيانات المهملة بحساب مراجع الكائنات . أولاً، قد يستغرق هذا وقتاً طويلاً. ثانيا، أنها ليست فعالة جدا. بعد كل شيء، يمكن للأشياء الرجوع إلى بعضها البعض! يوضح الشكل مثالاً حيث تشير 3 كائنات إلى بعضها البعض، ولكن لا يشير أي شخص آخر إليها. وبعبارة أخرى، فإن بقية البرنامج لا يحتاج إليها. إذا قام جامع البيانات المهملة بإحصاء المراجع ببساطة، فلن يتم جمع هذه الكائنات الثلاثة ولن يتم تحرير الذاكرة (توجد مراجع لها!). يمكننا مقارنة هذا بمركبة فضائية. أثناء الرحلة، قرر رواد الفضاء التحقق من قائمة قطع الغيار المتاحة للإصلاحات. من بين أمور أخرى، وجدوا عجلة القيادة والدواسات من سيارة عادية. من الواضح أنه ليست هناك حاجة إليهما هنا ويشغلان مساحة دون داع (على الرغم من أن هذين الجزأين مرتبطان ببعضهما البعض ولهما بعض الوظائف). لكن داخل المركبة الفضائية، فهي عبارة عن قمامة عديمة الفائدة ويجب التخلص منها. وفقًا لذلك، في Java، تم اتخاذ القرار بجمع البيانات المهملة ليس بناءً على العد المرجعي، ولكن على فصل الكائنات إلى نوعين: يمكن الوصول إليه وغير قابل للوصول. كيف نحدد ما إذا كان الشيء قابلاً للوصول؟ كل هذا ببساطة عبقري. يكون الكائن قابلاً للوصول إذا تمت الإشارة إليه بواسطة كائن آخر يمكن الوصول إليه. وهكذا نحصل على "سلسلة الوصول". يبدأ عندما يبدأ البرنامج ويستمر طوال مدة البرنامج. يبدو الأمر كما يلي: يشير السهم الموجود في الشكل إلى الكود القابل للتنفيذ لبرنامجنا. يقوم الكود (على سبيل المثال،
main()
الطريقة) بإنشاء مراجع للكائنات. يمكن أن تشير هذه الكائنات إلى كائنات أخرى، وتلك الكائنات إلى كائنات أخرى، وهكذا. وهذا يشكل سلسلة مرجعية . إذا كان بإمكانك التتبع على طول السلسلة من كائن إلى "المرجع الجذري" (الذي تم إنشاؤه مباشرة في التعليمات البرمجية القابلة للتنفيذ)، فسيتم اعتباره قابلاً للوصول. يتم تمييز هذه الكائنات باللون الأسود في الصورة. لكن لا يمكن الوصول إلى الكائن إذا خرج من هذه السلسلة، أي أن أيًا من المتغيرات الموجودة في الكود الذي يتم تنفيذه حاليًا لا يشير إليه، ولا يمكن الوصول إليه من خلال "السلسلة المرجعية". في برنامجنا، يتم تمييز اثنين من هذه الكائنات باللون الأحمر. لاحظ أن هذه الكائنات "الحمراء" لها إشارات إلى بعضها البعض. ولكن كما قلنا سابقًا، فإن أداة تجميع البيانات المهملة الحديثة في Java لا تحسب المراجع. فهو يحدد ما إذا كان الكائن يمكن الوصول إليه أم لا . ونتيجة لذلك، فإنه سوف يمسك بالجسمين الأحمرين في الشكل. الآن دعونا نلقي نظرة على العملية برمتها من البداية إلى النهاية. ومن خلال القيام بذلك، سنرى أيضًا كيفية ترتيب الذاكرة في Java :) يتم تخزين جميع كائنات Java في منطقة خاصة من الذاكرة تسمى الكومة . في اللغة اليومية، عادة ما تكون الكومة عبارة عن جبل من العناصر، حيث يختلط كل شيء. ولكن هذا ليس ما هو الكومة في جافا. هيكلها منطقي ومعقول للغاية. في مرحلة ما، وجد مبرمجو جافا أن جميع كائناتهم يمكن تقسيمها إلى نوعين: كائنات بسيطة و "كائنات طويلة العمر" . "الكائنات طويلة العمر" هي الكائنات التي نجت من عدة جولات من تجميع البيانات المهملة. وعادة ما يعيشون حتى انتهاء البرنامج. في النهاية، تم تقسيم الكومة الكاملة، حيث يتم تخزين جميع الكائنات، إلى عدة أجزاء. الجزء الأول له اسم جميل: عدن(من "جنة عدن" الكتابية). هذا الاسم مناسب، لأن هذا هو المكان الذي تنتهي فيه الكائنات بعد إنشائها. هذا هو الجزء من الذاكرة الذي يتم فيه إنشاء كائنات جديدة عندما نستخدم الكلمة الأساسية الجديدة. يمكن إنشاء الكثير من الكائنات. عند نفاد مساحة هذه المنطقة، تبدأ عملية تجميع البيانات المهملة "السريعة" الأولية. يجب أن نقول أن جامع القمامة ذكي جدًا. يختار خوارزمية بناءً على ما إذا كانت الكومة تحتوي على المزيد من البيانات المهملة أو المزيد من الكائنات الحية. إذا كانت جميع الكائنات تقريبًا عبارة عن نفايات، يقوم المجمع بوضع علامة على الكائنات الحية ونقلها إلى منطقة أخرى من الذاكرة. ثم يتم مسح المنطقة الحالية بالكامل. إذا لم يكن هناك الكثير من البيانات المهملة، وكانت الكومة عبارة عن كائنات حية في الغالب، يقوم المجمع بوضع علامة على البيانات المهملة، ومسحها، وحزم الكائنات الأخرى معًا. قلنا "يحدد المجمع الكائنات الحية وينقلها إلى منطقة أخرى من الذاكرة"، ولكن أين؟ تسمى منطقة الذاكرة التي يتم فيها نقل كافة الكائنات التي نجت على الأقل من جولة واحدة من تجميع البيانات المهملة بمساحة البقاء . مساحة البقاء ، بدورها، مقسمة إلى أجيال . ينتمي كل كائن إلى جيل معين، اعتمادًا على عدد جولات جمع البيانات المهملة التي نجا منها. إذا كان الكائن قد نجا من جولة واحدة من جمع البيانات المهملة، فهو في "الجيل 1"؛ إذا كان 5، ثم "الجيل 5". تشكل عدن ومساحة البقاء معًا منطقة تسمى جيل الشباب . بالإضافة إلى الجيل الشاب، تحتوي الكومة على منطقة أخرى من الذاكرة تسمى الجيل القديم . هذه هي بالضبط المنطقة التي تنتهي فيها الأشياء طويلة العمر التي نجت من جولات عديدة من جمع القمامة. هناك مزايا لإبقائهم منفصلين عن الآخرين. يتم تنفيذ عملية جمع البيانات المهملة بالكامل فقط عندما يكون الجيل القديم ممتلئًا، أي أن هناك العديد من الكائنات طويلة العمر في البرنامج بحيث لا توجد ذاكرة كافية. تتضمن هذه العملية أكثر من منطقة واحدة من الذاكرة. بشكل عام، فهو يشمل جميع الكائنات التي تم إنشاؤها بواسطة جهاز Java. وبطبيعة الحال، يستغرق هذا المزيد من الوقت والموارد. هذا هو بالضبط القرار الذي تم اتخاذه لتخزين الأشياء طويلة العمر بشكل منفصل. يتم تنفيذ "التجميع السريع للقمامة" عند نفاد المساحة في المناطق الأخرى. وهذا يشمل منطقة واحدة فقط، مما يجعلها أسرع وأكثر كفاءة. أخيرًا، حتى عندما يتم ملء منطقة الكائنات طويلة العمر بالكامل، يتم تشغيل عملية جمع البيانات المهملة بالكامل. وبالتالي، يستخدم المجمع الأداة "الأثقل" فقط عندما يكون من المستحيل تجنبها. فيما يلي تمثيل مرئي لبنية الكومة وجمع البيانات المهملة:
GO TO FULL VERSION