عدّ المراجع

في علوم الحاسوب ، يعد عد المراجع أسلوبًا برمجيًا لتخزين عدد المراجع أو المؤشرات أو المقابض لمورد ما، مثل كائن أو كتلة من الذاكرة أو مساحة القرص وغيرها.

في خوارزميات جمع البيانات المهملة ، يمكن استخدام عدادات المراجع لإلغاء تخصيص الكائنات التي لم تعد هناك حاجة إليها.

المزايا والعيوب

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

مثال على قائمة دائرية من رسالة ماجستير عام 1985. [ 1 ] تُمثل المستطيلات أزواج cons ، مع عدد المراجع. حتى في حالة إزالة المؤشر العلوي الأيسر الوارد، تظل جميع الأعداد أكبر من صفر.

يتم تشغيل دورات جمع البيانات المهملة بشكل متكرر للغاية إذا كانت مجموعة الكائنات النشطة تشغل معظم الذاكرة المتاحة؛ ويتطلب ذلك مساحة إضافية ليكون فعالاً. لا يتدهور أداء عد المراجع مع انخفاض إجمالي المساحة الحرة. [ 2 ]

تُعدّ أعداد المراجع معلومات مفيدة تُستخدم كمدخلات لتحسينات وقت التشغيل الأخرى. على سبيل المثال، قد تعاني الأنظمة التي تعتمد بشكل كبير على الكائنات غير القابلة للتغيير، مثل العديد من لغات البرمجة الوظيفية، من انخفاض في الكفاءة نتيجةً لكثرة النسخ. مع ذلك، إذا كان المُصرّف (أو نظام التشغيل ) يعلم أن لكائن معين مرجعًا واحدًا فقط (كما هو الحال في معظم الأنظمة)، وأن هذا المرجع يُفقد عند إنشاء كائن جديد مشابه (كما في عبارة إلحاق السلسلة النصية )، فإنه يستطيع استبدال العملية بتغيير الكائن الأصلي.str ← str + "a"

يُعاني عدّ المراجع في شكله البسيط من ثلاثة عيوب رئيسية مقارنةً بجمع البيانات المهملة القائم على التتبع، وكلاهما يتطلب آليات إضافية لتحسينه:

  • تُعدّ التحديثات المتكررة التي تتطلبها هذه العملية مصدرًا لعدم الكفاءة. فبينما قد تؤثر عمليات جمع البيانات المهملة التتبعية سلبًا على الكفاءة من خلال تبديل السياق وأخطاء خطوط التخزين المؤقت، إلا أنها تعمل على فترات متباعدة نسبيًا، في حين أن الوصول إلى الكائنات يتم باستمرار. أيضًا، وبشكل أقل أهمية، يتطلب عدّ المراجع من كل كائن مُدار في الذاكرة حجز مساحة لعدّ المراجع. في عمليات جمع البيانات المهملة التتبعية، تُخزّن هذه المعلومات ضمنيًا في المراجع التي تُشير إلى ذلك الكائن، مما يوفر مساحة، على الرغم من أن عمليات جمع البيانات المهملة التتبعية، وخاصة التزايدية منها، قد تتطلب مساحة إضافية لأغراض أخرى.
  • لا تستطيع الخوارزمية البسيطة الموضحة أعلاه التعامل معتُعرف الحلقات المرجعية بأنهاكائن يشير إلى نفسه بشكل مباشر أو غير مباشر. لا تأخذ الآلية التي تعتمد كليًا على عدّ المراجع في الحسبان سلاسل الكائنات الدورية عند الحذف، لأن عدّ المراجع فيها مضمون أن يبقى غير صفري (انظر الصورة). توجد طرق لمعالجة هذه المشكلة، ولكنها قد تزيد من عبء وتعقيد عدّ المراجع . من ناحية أخرى، لا يلزم تطبيق هذه الطرق إلا على البيانات التي قد تُشكّل حلقات، والتي غالبًا ما تكون مجموعة فرعية صغيرة من جميع البيانات. إحدى هذه الطرق هي استخدامالمراجع الضعيفة، بينما تتضمن طريقة أخرى استخداممسح العلاماتالتي تُستدعى على فترات متباعدة للتنظيف.
  • في بيئة متزامنة، يجب أن تكون جميع تحديثات عدادات المراجع وتعديلات المؤشرات عمليات ذرية ، مما يُضيف تكلفة إضافية. هناك ثلاثة أسباب لمتطلبات الذرية: أولًا، قد يتم تحديث حقل عداد المراجع بواسطة عدة سلاسل عمليات، لذا يجب استخدام تعليمة ذرية مناسبة، مثل عملية المقارنة والتبديل (المكلفة)، لتحديث العدادات. ثانيًا، يجب أن يكون واضحًا أي كائن يفقد مرجعًا حتى يمكن إنقاص عداد مراجعه بشكل مناسب. لكن تحديد هذا الكائن ليس بالأمر البسيط في بيئة تحاول فيها عدة سلاسل عمليات تعديل المرجع نفسه (أي عندما يكون تضارب البيانات ممكنًا). أخيرًا، يوجد تضارب دقيق حيث تحصل إحدى سلاسل العمليات على مؤشر إلى كائن، ولكن قبل أن تزيد عداد مراجع الكائن، يتم حذف جميع المراجع الأخرى لهذا الكائن بشكل متزامن بواسطة سلاسل عمليات أخرى، ويتم استعادة الكائن، مما يؤدي إلى قيام سلسلة العمليات المذكورة بزيادة عداد مراجع كائن مستعاد.

إضافةً إلى ذلك، إذا تم تخصيص الذاكرة من قائمة حرة، فإن عدّ المراجع يعاني من ضعف في التوطين. لا يستطيع عدّ المراجع وحده نقل الكائنات لتحسين أداء ذاكرة التخزين المؤقت، لذا تُطبّق مُجمّعات البيانات المهملة عالية الأداء مُجمّع تتبع أيضًا. تعاني معظم التطبيقات (مثل تلك الموجودة في PHP وObjective-C) من ضعف أداء ذاكرة التخزين المؤقت لأنها لا تُطبّق نسخ الكائنات. [ 3 ]

تفسير الرسم البياني

عند التعامل مع مخططات جمع البيانات المهملة، من المفيد غالبًا التفكير في الرسم البياني المرجعي ، وهو رسم بياني موجه حيث تكون الرؤوس عبارة عن كائنات، وهناك حافة من كائن  A إلى كائن  B إذا كان A يحتوي على مرجع إلى  B. لدينا أيضًا رأس خاص أو رؤوس تمثل المتغيرات المحلية والمراجع التي يحتفظ بها نظام وقت التشغيل، ولا تذهب الحواف أبدًا إلى هذه العقد، على الرغم من أنه يمكن أن تذهب الحواف منها إلى عقد أخرى.

في هذا السياق، يُعرَّف عدد المراجع البسيط لكائن ما بأنه درجة الدخول لرأسه. حذف رأس يشبه جمع كائن. لا يمكن القيام بذلك إلا عندما لا يكون للرأس أي حواف واردة، لذا فهو لا يؤثر على درجة الخروج لأي رؤوس أخرى، ولكنه قد يؤثر على درجة الدخول لرؤوس أخرى، مما يؤدي إلى جمع الكائنات المقابلة لها أيضًا إذا أصبحت درجة دخولها صفرًا نتيجة لذلك.

يحتوي المكون المتصل الذي يضم الرأس الخاص على الكائنات التي لا يمكن جمعها، بينما تحتوي المكونات المتصلة الأخرى في الرسم البياني على بيانات غير قابلة للجمع فقط. إذا تم تطبيق خوارزمية جمع البيانات غير القابلة للجمع باستخدام عدّ المراجع، فيجب أن يحتوي كل مكون من هذه المكونات على دورة واحدة على الأقل؛ وإلا، فسيتم جمعها بمجرد أن ينخفض ​​عدد مراجعها (أي عدد الحواف الواردة) إلى الصفر.

معالجة عدم كفاءة التحديثات

قد يؤدي زيادة أو إنقاص عدد المراجع في كل مرة يتم فيها إنشاء مرجع أو حذفه إلى إعاقة الأداء بشكل ملحوظ. لا تقتصر هذه العمليات على استهلاك الوقت فحسب، بل إنها تُلحق الضرر بأداء الذاكرة المؤقتة وقد تؤدي إلى اختلالات في خط الأنابيب . حتى العمليات التي تتم للقراءة فقط، مثل حساب طول قائمة، تتطلب عددًا كبيرًا من عمليات القراءة والكتابة لتحديث المراجع باستخدام عدّ المراجع البسيط.

إحدى التقنيات البسيطة هي أن يقوم المترجم بدمج عدد من تحديثات المراجع المتقاربة في تحديث واحد. هذه التقنية فعّالة بشكل خاص للمراجع التي يتم إنشاؤها وتدميرها بسرعة. مع ذلك، يجب توخي الحذر لوضع التحديث المدمج في الموضع الصحيح لتجنب تحرير الذاكرة قبل الأوان.

تعتمد طريقة دويتش-بوبرو لحساب المراجع على حقيقة أن معظم تحديثات عدد المراجع تُنشأ في الواقع من مراجع مخزنة في متغيرات محلية. تتجاهل هذه الطريقة هذه المراجع، وتقتصر على حساب المراجع في هياكل البيانات فقط. ولكن قبل حذف كائن ذي عدد مراجع صفري، يجب على النظام التحقق، من خلال مسح المكدس والسجلات، من عدم وجود أي مرجع آخر له.

تتضمن تقنية أخرى ابتكرها هنري بيكر الزيادات المؤجلة [ 4 ] ، حيث لا تُزيد المراجع المخزنة في متغيرات محلية عداد المراجع المقابل لها فورًا، بل تُؤجل هذه الزيادة إلى حين الحاجة إليها. إذا تم حذف هذا المرجع بسرعة، فلا داعي لتحديث العداد. هذا يُلغي عددًا كبيرًا من التحديثات المرتبطة بالمراجع قصيرة العمر (مثل مثال عدّ طول القائمة المذكور أعلاه). مع ذلك، إذا نُسخ هذا المرجع إلى بنية بيانات، فيجب إجراء الزيادة المؤجلة في ذلك الوقت. من الأهمية بمكان أيضًا إجراء الزيادة المؤجلة قبل أن ينخفض ​​عداد الكائن إلى الصفر، لتجنب تحرير الذاكرة قبل الأوان.

حقق ليفانوني وبيترانك انخفاضًا ملحوظًا في الحمل الزائد لتحديثات العداد . [ 5 ] [ 6 ] وقد قدّما طريقة دمج التحديثات التي تجمع العديد من تحديثات عداد المراجع الزائدة. لنفترض مؤشرًا يتم تحديثه عدة مرات خلال فترة زمنية محددة من التنفيذ. يشير أولًا إلى كائن O1، ثم إلى كائن آخر O2، وهكذا حتى يشير في نهاية الفترة إلى كائن ما On. عادةً ما تُنفّذ خوارزمية عدّ المراجع التحديثات 1 ، 2 rc(O1)--، rc(O2)++3 rc(O2)--، rc(O3)++4 rc(O3)--، ... ...rc(On)++rc(O1)--rc(On)++

أظهر ليفانوني وبيترانك في عام 2001 كيفية استخدام دمج التحديثات في جامع عدادات المراجع. عند استخدام دمج التحديثات مع معالجة مناسبة للكائنات الجديدة، يتم التخلص من أكثر من 99% من تحديثات العداد في معايير الأداء النموذجية للغة جافا.

ومن المثير للاهتمام أن دمج التحديثات يُلغي الحاجة إلى استخدام العمليات الذرية أثناء تحديثات المؤشرات في بيئة متزامنة، مما يحل مشكلات عدّ المراجع في هذه البيئة. وبالتالي، يحل دمج التحديثات المشكلة الثالثة المتمثلة في عدّ المراجع البسيط (أي التكلفة الإضافية الباهظة في بيئة متزامنة). وقدّم ليفانوني وبيترانك خوارزمية محسّنة يمكن تشغيلها بالتزامن مع التطبيقات متعددة الخيوط باستخدام التزامن الدقيق فقط. [ 7 ]

تجمع طريقة بلاكبيرن وماكينلي لحساب المراجع اللاحقة في عام 2003 [ 8 ] بين حساب المراجع المؤجل وحضانة النسخ، حيث لاحظا أن غالبية طفرات المؤشرات تحدث في الكائنات الحديثة. تحقق هذه الخوارزمية إنتاجية مماثلة لأسرع جامعات النسخ الجيلية مع فترات توقف محدودة منخفضة لحساب المراجع.

التعامل مع دورات المرجعية

لعلّ أوضح طريقة للتعامل مع حلقات المراجع هي تصميم النظام بحيث يتجنب إنشائها. قد يمنع النظام صراحةً حلقات المراجع؛ وغالبًا ما تفعل أنظمة الملفات ذات الروابط الصلبة ذلك. كما أن الاستخدام الحكيم للمراجع "الضعيفة" (غير المحسوبة) قد يساعد في تجنب حلقات الاحتفاظ؛ فعلى سبيل المثال، يوصي إطار عمل Cocoa باستخدام المراجع "القوية" للعلاقات بين الأصل والفرع، والمراجع "الضعيفة" للعلاقات بين الفرع والأصل. [ 9 ]

قد تُصمَّم الأنظمة أيضًا لتحمّل الحلقات التي تُنشئها أو تصحيحها بطريقة ما. قد يُصمِّم المطورون شيفرةً برمجيةً لـ"إزالة" المراجع في بنية بياناتٍ ما بشكلٍ صريحٍ عندما لا تعود هناك حاجةٌ إليها، مع أنَّ هذا يُكلِّفهم تتبُّع دورة حياة تلك البنية يدويًا. يُمكن أتمتة هذه التقنية بإنشاء كائن "مالك" يقوم بالإزالة عند تدميره؛ على سبيل المثال، يُمكن لمدمِّر كائن الرسم البياني حذف حواف عُقد الرسم البياني، ما يُنهي حلقات المراجع في الرسم البياني. بل قد يتم تجاهل الحلقات في الأنظمة ذات الأعمار القصيرة وكمية البيانات غير المُستخدَمة في الحلقات، لا سيما عندما تم تطوير النظام باستخدام منهجية تجنُّب هياكل البيانات الحلقية قدر الإمكان، عادةً على حساب الكفاءة.

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

يصف بيكون خوارزمية لجمع الحلقات لحساب المراجع، وهي مشابهة لخوارزميات تتبع المراجع، بما في ذلك نفس الحدود الزمنية النظرية. تعتمد هذه الخوارزمية على ملاحظة أنه لا يمكن عزل الحلقة إلا عندما ينخفض ​​عدد المراجع إلى قيمة غير صفرية. تُوضع جميع الكائنات التي يحدث فيها هذا الانخفاض في قائمة الجذور ، ثم يبحث البرنامج دوريًا في الكائنات التي يمكن الوصول إليها من الجذور عن الحلقات. ويعرف البرنامج أنه عثر على حلقة قابلة للجمع عندما يؤدي انخفاض جميع أعداد المراجع في حلقة المراجع إلى خفضها جميعًا إلى الصفر. [ 10 ] وقد طور باز وآخرون [ 11 ] نسخة محسّنة من هذه الخوارزمية ، قادرة على العمل بالتزامن مع عمليات أخرى، وتحسين كفاءتها باستخدام طريقة دمج التحديثات لليفانوني وبيترانك. [ 5 ] [ 6 ]

أشكال مختلفة

على الرغم من إمكانية تحسين عمليات عدّ المراجع البسيطة بطرقٍ متنوعة، إلا أنه غالبًا ما يُمكن إيجاد حلٍّ أفضل من خلال إجراء عدّ المراجع بطريقةٍ مختلفةٍ جذريًا. سنصف هنا بعضًا من هذه الطرق المختلفة لعدّ المراجع، ومزاياها وعيوبها.

العد المرجعي المرجح

في عدّ المراجع الموزون، يُخصّص لكل مرجع وزن ، ولا يتتبع كل كائن عدد المراجع التي تشير إليه، بل الوزن الإجمالي لتلك المراجع. المرجع الأولي لكائن مُنشأ حديثًا له وزن كبير، مثل 2 16. عند نسخ هذا المرجع، ينتقل نصف الوزن إلى المرجع الجديد، ويبقى النصف الآخر مع المرجع القديم. ولأن الوزن الإجمالي لا يتغير، فلا حاجة لتحديث عدّ المراجع الخاص بالكائن.

يؤدي حذف مرجع إلى إنقاص الوزن الإجمالي بمقدار وزن ذلك المرجع. وعندما يصبح الوزن الإجمالي صفرًا، تكون جميع المراجع قد حُذفت. إذا جرت محاولة نسخ مرجع بوزن 1، فيجب "زيادة وزن" المرجع بإضافة وزن إلى الوزن الإجمالي، ثم إضافة هذا الوزن الجديد إلى المرجع، ثم تقسيمه. يُمكن في هذه الحالة إنشاء كائن مرجع غير مباشر ، حيث يُنشأ المرجع الأولي إليه بوزن كبير يُمكن تقسيمه لاحقًا.

تُعدّ خاصية عدم الحاجة إلى الوصول إلى عدّاد المراجع عند نسخ مرجع ما مفيدةً للغاية، خاصةً عندما يكون الوصول إلى عدّاد المراجع الخاص بالكائن مكلفًا، على سبيل المثال لأنه موجود في عملية أخرى، أو على القرص، أو حتى عبر الشبكة. كما يُمكن أن تُساهم هذه الخاصية في زيادة التزامن من خلال تجنّب قيام العديد من الخيوط بقفل عدّاد المراجع لزيادته. ولذلك، يُعدّ عدّ المراجع الموزون مفيدًا للغاية في التطبيقات المتوازية، ومتعددة العمليات، وقواعد البيانات، والتطبيقات الموزّعة.

تكمن المشكلة الرئيسية في عدّ المراجع الموزونة البسيط في أن حذف مرجع ما يتطلب الوصول إلى عداد المراجع، وإذا تم حذف العديد من المراجع، فقد يتسبب ذلك في نفس الاختناقات التي نسعى لتجنبها. تحاول بعض التعديلات على عدّ المراجع الموزونة تجنب ذلك عن طريق نقل الوزن من مرجع مُحتضر إلى مرجع نشط.

تم ابتكار طريقة العد المرجعي المرجح بشكل مستقل من قبل بيفان [ 12 ] وواتسون وواتسون [ 13 ] في عام 1987.

عد المراجع غير المباشر

في عدّ المراجع غير المباشر، من الضروري تتبع مصدر المرجع. وهذا يعني الاحتفاظ بمرجعين للكائن: مرجع مباشر يُستخدم للاستدعاءات، ومرجع غير مباشر يُشكّل جزءًا من شجرة انتشار، كما في خوارزمية ديكسترا-شولتن ، التي تُمكّن جامع البيانات المهملة من تحديد الكائنات غير المستخدمة. يمنع هذا الأسلوب التخلص من الكائن قبل الأوان.

أمثلة على الاستخدام

جمع القمامة

تعتمد خوارزمية عدّ المراجع، كخوارزمية تجميع، على تتبع عدد المراجع التي تحتفظ بها الكائنات الأخرى لكل كائن. إذا وصل عدد مراجع الكائن إلى الصفر، يصبح الكائن غير قابل للوصول، ويمكن حذفه.

عند إتلاف كائن، ينخفض ​​عدد مراجع أي كائنات أخرى يشير إليها هذا الكائن. ولهذا السبب، قد يؤدي حذف مرجع واحد إلى تحرير عدد كبير من الكائنات. يسمح تعديل شائع بجعل عدّ المراجع تزايديًا: فبدلًا من إتلاف الكائن بمجرد أن يصبح عدد مراجعه صفرًا، يُضاف إلى قائمة الكائنات غير المُشار إليها، ويتم إتلاف عنصر واحد أو أكثر من هذه القائمة دوريًا (أو حسب الحاجة).

تتطلب عدادات المراجع البسيطة تحديثات متكررة. فعندما يتم حذف مرجع أو استبداله، يتم إنقاص عداد المراجع الخاص بالكائن الذي يشير إليه، وعندما يتم إنشاء مرجع جديد أو نسخه، يتم زيادة عداد المراجع الخاص بالكائن الذي يشير إليه.

يُستخدم عدّ المراجع أيضًا في أنظمة الملفات والأنظمة الموزعة، حيث يكون جمع البيانات المهملة الكامل غير التزايدي مستهلكًا للوقت بشكل كبير نظرًا لحجم مخطط الكائنات وبطء سرعة الوصول. [ 14 ]

نموذج كائن المكون

يستخدم نموذج كائنات المكونات (COM) من مايكروسوفت ونظام التشغيل WinRT عدّ المراجع على نطاق واسع. في الواقع، اثنتان من الطرق الثلاث التي يجب أن توفرها جميع كائنات COM (في واجهة IUnknown ) تُستخدمان لزيادة أو إنقاص عدّ المراجع. يعتمد جزء كبير من واجهة ويندوز والعديد من تطبيقات ويندوز (بما في ذلك متصفح إنترنت إكسبلورر ، وحزمة مايكروسوفت أوفيس ، والعديد من منتجات الجهات الخارجية) على COM، مما يُثبت جدوى عدّ المراجع في الأنظمة واسعة النطاق.

يتمثل أحد الدوافع الرئيسية لاستخدام عدّ المراجع في COM في تمكين التوافق بين لغات البرمجة وأنظمة التشغيل المختلفة. يكفي أن يعرف المستخدم كيفية استدعاء توابع الكائن لإدارة دورة حياته؛ وبالتالي، يكون المستخدم معزولًا تمامًا عن مُخصِّص الذاكرة الذي يستخدمه تطبيق كائن COM. على سبيل المثال، لا يتأثر برنامج Visual Basic الذي يستخدم كائن COM بما إذا كان هذا الكائن قد تم تخصيصه (ويجب تحريره لاحقًا) بواسطة مُخصِّص ذاكرة C++ أو مكون Visual Basic آخر.

لغة سي++

لا تُجري لغة C++ عدّ المراجع افتراضيًا، التزامًا منها بفلسفتها المتمثلة في عدم إضافة وظائف قد تُسبب أعباءً إضافية ما لم يطلبها المستخدم صراحةً. ويمكن الوصول إلى الكائنات المشتركة غير المملوكة عبر مرجع أو مؤشر خام أو مُكرِّر (وهو تعميم مفاهيمي للمؤشرات).

مع ذلك، توفر لغة C++ طرقًا أصلية للمستخدمين لتفعيل هذه الوظيفة: إذ يوفر الإصدار C++11 مؤشرات ذكية مع عدّ المراجع ، عبر std::shared_ptrالفئة، مما يُمكّن من إدارة الذاكرة المشتركة تلقائيًا للكائنات المُخصصة ديناميكيًا. يمكن للمبرمجين استخدام هذه الميزة بالتزامن مع المؤشرات الضعيفة (عبر std::weak_ptr) لكسر التبعيات الدائرية. أما الكائنات المُخصصة ديناميكيًا ولكن غير المُراد مشاركتها، فيمكن إدارة دورة حياتها تلقائيًا باستخدام std::unique_ptr.

بالإضافة إلى ذلك، فإن دلالات النقل في C++11 تقلل بشكل أكبر من مدى الحاجة إلى تعديل عدد المراجع عن طريق إزالة النسخ العميق المستخدم عادةً عندما تُرجع دالة كائنًا، حيث يسمح ذلك بنسخ بسيط لمؤشر الكائن المذكور.

الكاكاو (Objective-C)

تستخدم أطر عمل Cocoa و Cocoa Touch من Apple (وأطر العمل ذات الصلة، مثل Core Foundation ) عدّ المراجع اليدوي، على غرار COM . تقليديًا، كان المبرمج يُنجز ذلك بإرسال رسائل يدويًا retainإلى releaseالكائنات، ولكن أُضيفت ميزة عدّ المراجع التلقائي ، وهي ميزة في مُصرّف Clang تُدرج هذه الرسائل تلقائيًا عند الحاجة، في نظامي iOS 5 [ 15 ] و Mac OS X 10.7 [ 16 ] . قدّم نظام Mac OS X 10.5 جامع قمامة للتتبع كبديل لعدّ المراجع، ولكن تم إيقاف دعمه في نظام OS X 10.8 وإزالته من مكتبة وقت تشغيل Objective-C في macOS Sierra [ 17 ] [ 18 ] . لم يدعم نظام iOS جامع قمامة للتتبع مطلقًا.

دلفي

لا تُعتبر لغة دلفي لغةً تعتمد على جمع البيانات المهملة بشكلٍ أساسي، إذ لا يزال يتعين على المستخدم تخصيص وتحرير أنواع البيانات المُعرّفة يدويًا؛ ومع ذلك، فهي توفر جمعًا تلقائيًا للذاكرة باستخدام عدّ المراجع لبعض الأنواع المُدمجة، مثل السلاسل النصية والمصفوفات الديناميكية والواجهات، وذلك لتسهيل الاستخدام وتبسيط وظائف قواعد البيانات العامة. يعود القرار للمبرمج بشأن استخدام الأنواع المُدمجة؛ إذ يتمتع مبرمجو دلفي بإمكانية الوصول الكامل إلى إدارة الذاكرة منخفضة المستوى كما هو الحال في لغتي C/C++. وبالتالي، يُمكن تجاوز جميع التكاليف المُحتملة لعدّ المراجع في دلفي بسهولة، إذا رغب المبرمج بذلك.

تتضمن بعض الأسباب التي ربما جعلت نظام العد المرجعي مفضلاً على أشكال جمع القمامة الأخرى في دلفي ما يلي:

  • الفوائد العامة لعد المراجع، مثل جمع العينات على وجه السرعة.
  • إما أن الحلقات لا يمكن أن تحدث أو لا تحدث في الواقع العملي لأن أياً من الأنواع المضمنة التي يتم جمعها بواسطة جامع البيانات المهملة ليست تكرارية. (يمكن إنشاء مثل هذا السيناريو باستخدام الواجهات، لكن هذا ليس استخداماً شائعاً)
  • إن الحمل الزائد في حجم التعليمات البرمجية المطلوبة لعد المراجع صغير جدًا (على x86 الأصلي، عادةً ما تكون تعليمة LOCK INC أو LOCK DEC أو LOCK XADD واحدة، مما يضمن الذرية في أي بيئة)، ولا حاجة إلى سلسلة تحكم منفصلة للتجميع كما هو مطلوب لجامع القمامة التتبعي.
  • تتميز العديد من حالات النوع الأكثر استخدامًا في جمع البيانات المهملة، وهو السلسلة النصية، بعمر قصير، نظرًا لأنها عادةً ما تكون قيمًا وسيطة في معالجة السلاسل النصية. يمكن تحسين الكثير من استخدام السلاسل النصية المحلية، لكن المترجم لا يقوم بذلك حاليًا.
  • يتم التحقق من عدد المراجع في السلسلة النصية قبل تعديلها. يسمح هذا بتعديل السلاسل النصية ذات عدد المراجع 1 مباشرةً، بينما تُنسخ السلاسل النصية ذات عدد المراجع الأعلى قبل التعديل. يتيح هذا الحفاظ على السلوك العام لسلاسل باسكال القديمة مع التخلص من تكلفة نسخ السلسلة في كل عملية إسناد.
  • بما أن عملية جمع البيانات المهملة تتم فقط على الأنواع المضمنة، يمكن دمج عدّ المراجع بكفاءة في إجراءات المكتبة المستخدمة لمعالجة كل نوع بيانات، مما يقلل من الحمل الزائد اللازم لتحديث عدّ المراجع. علاوة على ذلك، فإن جزءًا كبيرًا من مكتبة وقت التشغيل مكتوب بلغة تجميع مُحسَّنة يدويًا.
  • يمكن تحويل نوع السلسلة النصية إلى مؤشر إلى حرف، مما يتيح تنفيذ عمليات عالية الأداء. وهذا أمر بالغ الأهمية لأن كلاً من دلفي وFPC تُنفذان لغة RTL الخاصة بهما بلغة باسكال. كما تتوفر خيارات تحويل مماثلة لأنواع البيانات الآلية الأخرى.

كائن G

يُطبّق إطار عمل البرمجة الكائنية GObject عدّ المراجع على أنواعه الأساسية، بما في ذلك المراجع الضعيفة . ويستخدم زيادة المراجع وإنقاصها عمليات ذرية لضمان سلامة الخيوط. ويكمن جزء كبير من العمل في كتابة روابط GObject من لغات البرمجة عالية المستوى في تكييف عدّ المراجع في GObject ليتوافق مع نظام إدارة الذاكرة الخاص باللغة.

تستخدم لغة البرمجة Vala نظام عد المراجع GObject كنظام أساسي لجمع البيانات المهملة، بالإضافة إلى معالجة السلاسل النصية التي تتطلب نسخًا مكثفة. [ 19 ]

بيرل

يستخدم بيرل أيضًا عد المراجع، دون أي معالجة خاصة للمراجع الدائرية، على الرغم من أن بيرل (كما هو الحال في Cocoa و C++ أعلاه) يدعم المراجع الضعيفة، مما يسمح للمبرمجين بتجنب إنشاء حلقة.

PHP

تستخدم لغة PHP آلية عدّ المراجع لإدارة متغيراتها الداخلية. [ 20 ] ومنذ الإصدار 5.3، تُطبّق PHP الخوارزمية المذكورة في ورقة بيكون البحثية السابقة. تتيح لك PHP تفعيل وإيقاف عملية جمع البيانات الدورية باستخدام دوال على مستوى المستخدم. كما تتيح لك فرض تشغيل آلية التطهير يدويًا.

$a = "سلسلة جديدة" ; $b = $a ; xdebug_debug_zval ( "a" );

سيُخرج المثال أعلاه ما يلي:

أ: (refcount=2, is_ref=0)='سلسلة نصية جديدة'

بايثون

تستخدم لغة بايثون أيضًا عدّ المراجع وتوفر خاصية اكتشاف الحلقات (ويمكنها استعادة حلقات المراجع). [ 21 ]

الصدأ

على غرار لغات البرمجة منخفضة المستوى الأخرى، لا توفر لغة Rust عدّ المراجع افتراضيًا. بدلًا من ذلك، يُحذف أي نوع مُنشأ عند خروجه من نطاق التعريف. وعندما يحتاج المبرمج إلى تحديد نطاق نوع مُنشأ، فإنه غالبًا ما يستخدم دورات الحياة.

مع ذلك، توفر اللغة أيضًا بدائل متنوعة لأساليب إدارة الذاكرة المعقدة. وتُوفّر وظيفة عدّ المراجع بواسطة النوعين std::rc::Rcو std::sync::Arc، وهما نوعان غير ذريين وذريين على التوالي.

على سبيل المثال، يوفر هذا النوع std::rc::Rc<T>ملكية مشتركة لقيمة من النوع T، مخصصة على الكومة لعدة مراجع لبياناتها. [ 22 ]

استخدم std :: rc :: Rc ؛struct Cat { color : String , }fn main () { let cat = Cat { color : "black" . to_string () }; let cat = Rc :: new ( cat ); }

يُمكّن استخدام هذه البنى المبرمجين من تجنب دورات حياة المتغيرات بتكلفة تشغيلية بسيطة. ويحتفظ كلا عدادَي المراجع بسجل عدد المالكين، إذ يجب عليهما حذف أنفسهما عندما لا يتبقى أي مالك.

من الجوانب الجديرة بالذكر لهذه الأنواع استخدامها كمرجع مشترك. في لغة Rust، لا يمكن للمراجع المشتركة تعديل البيانات المخزنة فيها، لذا std::rc::Rcغالبًا ما تأتي مُدمجة مع `<<<>` و` std::cell::Cell<<< >` في السياقات التي تتطلب قابلية التعديل الداخلي.std::sync::Arcstd::sync::Mutex

إن قابلية التغيير الداخلية بدون std::cell::UnsafeCellتكلفة أداء أيضًا، لذلك، لتحقيق أقصى أداء، قد تتطلب بعض التطبيقات تعقيدًا إضافيًا. [ 23 ]

السنجاب

تستخدم لغة البرمجة Squirrel عدّ المراجع مع اكتشاف الحلقات. هذه اللغة الصغيرة غير معروفة نسبيًا خارج صناعة ألعاب الفيديو؛ ومع ذلك، فهي مثال ملموس على كيفية عمل عدّ المراجع بكفاءة وفعالية (خاصة في بيئات الوقت الحقيقي).

سويفت

تستخدم لغة Swift عدّ المراجع لتتبع وإدارة ذاكرة مثيلات الفئات، وتوفر weakالكلمة المفتاحية لإنشاء مراجع ضعيفة. أما مثيلات أنواع القيم فلا تستخدم عدّ المراجع. [ 24 ]

تي سي إل

تستخدم لغة Tcl 8 عدّ المراجع لإدارة الذاكرة للقيم ( هياكل Tcl Obj ). ولأن قيم Tcl غير قابلة للتغيير، يستحيل تكوّن حلقات مرجعية، ولا حاجة إلى آلية للكشف عن الحلقات. تُحسَّن العمليات التي تستبدل قيمةً بنسخة مُعدَّلة، عادةً، لتعديل القيمة الأصلية عندما يُشير عدّ المراجع إلى أنها غير مشتركة. تُحسب المراجع على مستوى بنية البيانات، لذا لا تظهر مشاكل التحديثات المتكررة المذكورة سابقًا.

زوجو

يستخدم Xojo أيضًا عد المراجع، دون أي معالجة خاصة للمراجع الدائرية، على الرغم من (كما هو الحال في Cocoa و C++ أعلاه)، فإن Xojo يدعم المراجع الضعيفة، مما يسمح للمبرمجين بتجنب إنشاء حلقة.

أنظمة الملفات

تحتفظ العديد من أنظمة الملفات بعدد المراجع لأي كتلة أو ملف معين، على سبيل المثال، عدد روابط inode في أنظمة الملفات الشبيهة بنظام يونكس ، والتي تُعرف عادةً بالروابط الصلبة . عندما يصل العدد إلى الصفر، يمكن تحرير الملف بأمان. مع أنه لا يزال بالإمكان إنشاء المراجع من الدلائل ، إلا أن بعض أنظمة يونكس لا تسمح إلا بالمراجع من العمليات الجارية، وقد توجد ملفات خارج التسلسل الهرمي لنظام الملفات.

مراجع

  1. كيفن ج. كاسيدي (ديسمبر 1985). جدوى استعادة التخزين التلقائي مع تنفيذ البرامج المتزامن في بيئة LISP (ملف PDF) (رسالة ماجستير). كلية الدراسات العليا البحرية، مونتيري/كاليفورنيا.هنا: صفحة 25
  2. ويلسون، بول ر. (1992). "تقنيات جمع البيانات المهملة للمعالج الأحادي" . وقائع ورشة العمل الدولية حول إدارة الذاكرة . لندن، المملكة المتحدة: سبرينغر-فيرلاغ. ص 1-42 . ISBN  3-540-55940-X.القسم 2.1.
  3. رفعت شهريار، ستيفن إم. بلاكبيرن، شي يانغ، وكاثرين إس. ماكينلي (2013). "التعامل مع خوارزمية Immix لحساب المراجع" (ملف PDF) . المؤتمر الرابع والعشرون لجمعية ACM SIGPLAN حول أنظمة ولغات وتطبيقات البرمجة الكائنية التوجه . OOPSLA 2013. doi : 10.1145/2509136.2509527 .{{cite conference}}: صيانة CS1: أسماء متعددة: قائمة المؤلفين ( رابط )
  4. هنري بيكر (سبتمبر 1994). "تقليل تحديث عدد المراجع باستخدام المؤشرات المؤجلة والمثبتة لهياكل البيانات الوظيفية". إشعارات ACM SIGPLAN . 29 (9): 38-43 . CiteSeerX 10.1.1.25.955 . doi : 10.1145/185009.185016 . S2CID 14448488 .  
  5. 1 2 يوسي ليفانوني، إيريز بيترانك (2001). "جامع قمامة يعمل على عدّ المراجع أثناء التشغيل للغة جافا" . وقائع المؤتمر السادس عشر لجمعية ACM SIGPLAN حول البرمجة الكائنية التوجه، والأنظمة، واللغات، والتطبيقات . OOPSLA 2001. الصفحات 367-380 . doi : 10.1145/504282.504309 . 
  6. 1 2 يوسي ليفانوني، إيريز بيترانك (2006). "جامع قمامة يعمل على عدّ المراجع أثناء التشغيل للغة جافا" . معاملات ACM في لغات البرمجة والأنظمة . 28 : 31-69 . CiteSeerX 10.1.1.15.9106 . doi : 10.1145/1111596.1111597 . S2CID 14777709 .  
  7. "جامع قمامة يعمل على عدّ المراجع أثناء التشغيل للغة جافا" (ملف PDF) . Cs.technion.ac.il . تاريخ الاسترجاع: 24 يونيو 2017 .
  8. ستيفن بلاكبيرن؛ كاثرين ماكينلي (2003). "العد المرجعي الخفي: جمع البيانات المهملة بسرعة دون انتظار طويل" (ملف PDF) . وقائع المؤتمر السنوي الثامن عشر لجمعية ACM SIGPLAN حول البرمجة كائنية التوجه، والأنظمة، واللغات، والتطبيقات . OOPSLA 2003. الصفحات 344-358 . doi : 10.1145/949305.949336 . ISBN  1-58113-712-5.
  9. "مكتبة مطوري ماك" . Developer.apple.com . تم الاطلاع عليه بتاريخ 17 ديسمبر 2015 .
  10. بيكون، ديفيد ف.؛ راجان، في تي (2001). "تجميع الدورات المتزامنة في أنظمة عد المراجع" (ملف PDF) . ECOOP 2001 - البرمجة كائنية التوجه . سلسلة محاضرات في علوم الحاسوب. المجلد 2072. الصفحات 207-235 . doi : 10.1007/3-540-45337-7_12 . ISBN   978-3-540-42206-8تمت أرشفة هذا الملف من النسخة الأصلية (PDF) بتاريخ 23 يوليو 2004.
  11. هاريل باز، ديفيد ف. بيكون، إليوت ك. كولودنر، إيريز بيترانك ، في تي راجان (2007). "جمع دورات فعال أثناء التنفيذ". معاملات ACM في لغات البرمجة والأنظمة . 29 (4): 20–es. CiteSeerX 10.1.1.10.2777 . doi : 10.1145/1255450.1255453 . S2CID 4550008 .  {{cite journal}}: صيانة CS1: أسماء متعددة: قائمة المؤلفين ( رابط )
  12. بيفان، دي آي (1987). "جمع البيانات المهملة الموزع باستخدام عد المراجع". المجلد الثاني: اللغات المتوازية في PARLE: البنى واللغات المتوازية في أوروبا . أيندهوفن، هولندا: سبرينغر-فيرلاغ. الصفحات 176-187 . ISBN  0-387-17945-3.
  13. واتسون، بول؛ واتسون، إيان (1987). "مخطط فعال لجمع البيانات المهملة لبنى الحواسيب المتوازية". المجلد الثاني: اللغات المتوازية في PARLE: البنى واللغات المتوازية في أوروبا . أيندهوفن، هولندا: سبرينغر-فيرلاغ. الصفحات 432-443 . ISBN  0-387-17945-3.
  14. برونو، رودريغو؛ فيريرا، باولو (2018). "دراسة حول خوارزميات جمع البيانات المهملة لبيئات البيانات الضخمة". مجلة ACM Computing Surveys . 51 : 1-35 . doi : 10.1145/3156818 . S2CID 21388487 . 
  15. أُرشف بتاريخ 9 يونيو 2011 في أرشيف الإنترنت (Wayback Machine).
  16. "مكتبة مطوري ماك" . Developer.apple.com . تم الاطلاع عليه بتاريخ 17 ديسمبر 2015 .
  17. سيراكوزا، جون (25 يوليو 2012). "نظام التشغيل OS X 10.8 ماونتن ليون: مراجعة آرس تكنيكا" . آرس تكنيكا . في قسم "تحسينات Objective-C" . تم الاطلاع عليه بتاريخ 17 نوفمبر 2016 .
  18. "ملاحظات إصدار Xcode 8" . مطورو Apple . 27 أكتوبر 2016. مؤرشف من الأصل في 19 مارس 2017. تم الاطلاع عليه في 19 مارس 2017 .
  19. "Projects/Vala/ReferenceHandling - GNOME Wiki!" . جنوم. 25 مايو 2015. تم الاطلاع عليه بتاريخ 17 ديسمبر 2015 .
  20. "PHP: أساسيات عدّ المراجع - دليل المستخدم" . www.php.net . تم الاطلاع عليه بتاريخ 1 أكتوبر 2020 .
  21. "1. توسيع بايثون باستخدام لغة C أو C++ — وثائق بايثون 2.7.11" . Docs.python.org. 5 ديسمبر 2015. تم الاطلاع عليه بتاريخ 17 ديسمبر 2015 .
  22. "std::rc - Rust" . doc.rust-lang.org . تم الاطلاع عليه في 2 نوفمبر 2020 .
  23. "مرجع الصدأ" . 21 يوليو 2022. قابلية التغيير الداخلي. مؤرشف من الأصل في 24 مارس 2024. تم الاسترجاع في 22 أبريل 2024 .
  24. "الوثائق" . docs.swift.org . تم الاطلاع عليه بتاريخ 6 ديسمبر 2023 .