مرجع ضعيف

في برمجة الحاسوب ، يُعرف المرجع الضعيف بأنه مرجع لا يحمي الكائن المُشار إليه من جمعه بواسطة جامع البيانات المهملة ، على عكس المرجع القوي. يُعتبر الكائن الذي يُشار إليه فقط بواسطة مراجع ضعيفة - أي "كل سلسلة مراجع تصل إلى الكائن تتضمن مرجعًا ضعيفًا واحدًا على الأقل كرابط" - قابلًا للوصول بشكل ضعيف ، ويمكن التعامل معه على أنه غير قابل للوصول ، وبالتالي قد يتم جمعه في أي وقت. تتميز بعض لغات البرمجة التي تستخدم جمع البيانات المهملة بمستويات مختلفة من المراجع الضعيفة أو تدعمها ، مثل C # و Lua و Java و Lisp و OCaml و MATLAB و Perl و Python و Racket و PHP منذ الإصدار 7.4 .

الاستخدامات

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

جمع القمامة

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

من الأمثلة الشائعة على التمييز بين المراجع القوية والضعيفة، هياكل الأشجار، مثل نموذج كائن المستند (DOM)، حيث تكون المراجع من الأصل إلى الفرع قوية، بينما تكون المراجع من الفرع إلى الأصل ضعيفة. على سبيل المثال، يوصي إطار عمل Cocoa من Apple بهذا النهج. [ 5 ] في الواقع، حتى عندما لا يكون مخطط الكائنات شجرة، يمكن فرض بنية شجرية غالبًا من خلال مفهوم ملكية الكائنات، حيث تكون علاقات الملكية قوية وتشكل شجرة، بينما تكون علاقات عدم الملكية ضعيفة وغير ضرورية لتشكيل الشجرة - هذا النهج شائع في لغة C++ (قبل C++11)، باستخدام المؤشرات الخام كمراجع ضعيفة. مع ذلك، يعيب هذا النهج عدم إمكانية اكتشاف حذف فرع الأصل. منذ معيار C++11 ، أُضيف حل باستخدام shared_ptr و weak_ptr ، الموروثتين من مكتبة Boost .

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

الاختلافات

تتضمن بعض لغات البرمجة مستويات متعددة من قوة المراجع الضعيفة. على سبيل المثال، تحتوي لغة جافا ، مرتبةً تنازليًا حسب القوة، على المراجع الناعمة ، والضعيفة ، والوهمية، والمُعرّفة في حزمة java.lang.ref . [ 6 ] لكل نوع من أنواع المراجع مفهومٌ خاصٌ بإمكانية الوصول إليه. يستخدم جامع البيانات المهملة (GC) نوع إمكانية الوصول إلى الكائن لتحديد وقت تحريره. من الآمن لجامع البيانات المهملة تحرير كائن يمكن الوصول إليه بشكل ناعم، لكنه قد يقرر عدم القيام بذلك إذا اعتقد أن آلة جافا الافتراضية (JVM) لديها مساحة ذاكرة غير مستخدمة كافية (مثلًا، إذا كان لدى آلة جافا الافتراضية مساحة كبيرة غير مستخدمة في الذاكرة). سيحرر جامع البيانات المهملة الكائن الذي يمكن الوصول إليه بشكل ضعيف بمجرد أن يلاحظه. على عكس أنواع المراجع الأخرى، لا يمكن تتبع المرجع الوهمي. من ناحية أخرى، توفر المراجع الوهمية آليةً لإعلام البرنامج عند تحرير كائن (يتم تنفيذ الإشعار باستخدام قوائم انتظار المراجع).

في لغة C#، تُفرَّق المراجع الضعيفة بناءً على ما إذا كانت تُتابع عملية إعادة إنشاء الكائن أم لا. لا ينطبق هذا التمييز على المراجع القوية، إذ لا تُعتبر الكائنات نهائية إذا كانت لها أي مراجع قوية إليها. افتراضيًا، لا تُتابع المراجع الضعيفة في C# عملية إعادة الإنشاء، أي أن المرجع الضعيف لا يُحدَّث عند إعادة إنشاء الكائن؛ وتُسمى هذه المراجع بالمراجع الضعيفة القصيرة ، بينما تُسمى المراجع الضعيفة التي تُتابع عملية إعادة الإنشاء بالمراجع الضعيفة الطويلة . [ 7 ]

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

أمثلة

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

لغة سي++

تحتوي لغة C++std::weak_ptr على فئة، وهي نوع من المؤشرات الذكية .

استيراد std ؛باستخدام std :: shared_ptr ؛ باستخدام std :: weak_ptr ؛shared_ptr < int [] > myInts = std :: make_shared < int [] > ( 5 ); weak_ptr < int [] > weakPtr = myInts ;

سي شارب

تحتوي لغة C#System.WeakReference على هذه الفئة. [ 8 ] [ 9 ]

باستخدام System ؛ باستخدام System.Collections.Generic ؛Dictionary < int , WeakReference > () myDict = new ();

جافا

قدّمت لغة جافا 1.2 في عام 1998 [ 10 ] نوعين من المراجع الضعيفة، أحدهما يُعرف باسم "المرجع اللين" (المُصمم للاستخدام في إدارة ذاكرة التخزين المؤقت المُدارة بواسطة جامع البيانات المهملة، ولكنه لا يعمل بكفاءة عالية عمليًا على بعض المنصات ذات الذاكرة الديناميكية مثل أندرويد [ 11 ] )، والآخر ببساطة "المرجع الضعيف". كما أضافت آلية تجريبية ذات صلة تُسمى "المراجع الوهمية" كبديل للآلية الخطيرة وغير الفعالة finalize(). [ 12 ]

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

package org.wikipedia.examples ;استيراد java.lang.ref.WeakReference ؛public class ReferenceTest { public static void main ( String [] args ) throws InterruptedException { WeakReference r = new WeakReference ( "أنا هنا" ); String s = "أنا هنا" ; System . out . printf ( "قبل عملية جمع البيانات المهملة: r=%s, static=%s%n" , r . get (), s ); System . gc (); // نفترض أن عملية جمع البيانات المهملة قيد التشغيل Thread . sleep ( 100 );// تصبح قيمة r.get ( ) فقط فارغة. System.out.printf ( "بعد عملية جمع البيانات المهملة: r=%s، static=%s%n" , r.get ( ) , s ) ; } }

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

أحاديث قصيرة

| a s1 s2 |s1 := 'hello' copy . "هذا مرجع قوي" s2 := 'world' copy . "هذا مرجع قوي" a := WeakArray with: s1 with: s2 . a printOn: Transcript . ObjectMemory collectGarbage . a printOn: Transcript . "لا يزال كلا العنصرين موجودين"s1 := nil . "تم حذف المرجع القوي" ObjectMemory collectGarbage . a printOn: Transcript . "تم حذف العنصر الأول"s2 := nil . "تم حذف المرجع القوي" ObjectMemory collectGarbage . a printOn: Transcript . "تم حذف العنصر الثاني"

لغة لوا

weak_table = setmetatable ( { } , { __mode = "v" } ) weak_table.item = { } print ( weak_table.item ) collectgarbage ( ) print ( weak_table.item )

أوبجكتيف-سي 2.0

في لغة Objective-C 2.0، لا تتأثر عملية جمع البيانات المهملة فحسب، بل تتأثر أيضًا عملية العد التلقائي للمراجع بالمراجع الضعيفة. جميع المتغيرات والخصائص في المثال التالي ضعيفة.

@interface WeakRef : NSObject { __weak NSString * str1 ; __unsafe_unretained NSString * str2 ; }@property ( nonatomic , weak ) NSString * str3 ; @property ( nonatomic , unsafe_unretained ) NSString * str4 ;@نهاية

الفرق بين weak( __weak) و unsafe_unretained( __unsafe_unretained) هو أنه عند تحرير الكائن الذي يشير إليه المتغير، لا تتغير قيمة المتغير. weakسيتم تحديث قيمة أحد المتغيرات إلى قيمة أخرى ، بينما سيبقى الآخر دون تغيير، كمؤشر nilمعلق . أُضيفت المراجع إلى لغة Objective-C منذ نظامي التشغيل Mac OS X 10.7 "Lion" و iOS 5 ، بالإضافة إلى Xcode 4.1 (4.2 لنظام iOS)، وذلك فقط عند استخدام ARC. تدعم الإصدارات الأقدم من Mac OS X و iOS و GNUstep المراجع كمراجع ضعيفة فقط .unsafe_unretainedweak    unsafe_unretained

PHP

تحتوي لغة PHP على فئة WeakReference . [ 14 ]

$obj = new stdClass (); $weakref = WeakReference :: create ( $obj );var_dump ( $weakref -> get ()); غير محدد ( $obj ); var_dump ( $weakref -> get ());

بايثون

تحتوي لغة بايثون على وحدة weakref . [ 15 ]

استيراد gc و weakref من weakref استيراد ReferenceTypeclass Egg : def spam ( self ) -> None : print ( "أنا على قيد الحياة!" )obj : Egg = Egg () weak_obj : ReferenceType [ Egg ] = weakref . ref ( obj ) weak_obj () . spam () # يطبع: أنا على قيد الحياة!obj : str = "Something else" # gc.collect() تُرجع عددًا صحيحًا print ( f "عدد الكائنات التي لا يمكن الوصول إليها التي تم جمعها: { gc . collect () } " ) # يطبع: عدد الكائنات التي لا يمكن الوصول إليها التي تم جمعها: 35 weak_obj () . spam () # Traceback (most recent call last): # File "<stdin>", line 1, in <module> # AttributeError: 'NoneType' object has no attribute 'spam'

الصدأ

يحتوي Ruststd::rc::Weak على كائن.

استخدم std :: rc :: Rc ؛ استخدم std :: rc :: Weak ؛let strong_ptr : Rc < i32 > = Rc :: new ( 5 ); let weak_ptr : Weak < i32 > = Rc :: downgrade ( & strong_ptr );

فالا

فالا لديها الكلمة المفتاحية الضعيفة . [ 16 ]

class Node { public weak Node prev ; // يتم استخدام مرجع ضعيف لتجنب المراجع الدائرية بين عقد القائمة المرتبطة ثنائياً public Node next ; }

انظر أيضاً

مراجع

  1. ليروساليمسكي، روبرتو (2003). "17 - الجداول الضعيفة". البرمجة بلغة لوا (  الطبعة الأولى).
  2. 8.8. weakref — المراجع الضعيفة ، مكتبة بايثون القياسية
  3. "PHP: WeakReference - Manual" .
  4. "إدارة الذاكرة العملية" . developer.apple.com .
  5. نيكولاس، إيثان (4 مايو 2006). "فهم المراجع الضعيفة" . java.net . مؤرشف من الأصل في 3 مارس 2011. تم الاطلاع عليه في 1 أكتوبر 2010 .
  6. غولدشتاين، زورباليف وفلاتو 2012 ، ص 131 . 
  7. "المراجع الضعيفة - .NET" . learn.microsoft.com . تم الاطلاع عليه بتاريخ 9 يوليو 2025 .
  8. "فئة المرجع الضعيف (النظام)" . learn.microsoft.com . تم الاطلاع عليه في 9 يوليو 2025 .
  9. ^ ""مرجع ضعيف (Java Platform SE 7)" . docs.Oracle.com .
  10. "SoftReference - Android Developers" . developer.android.com .
  11. "PhantomReference (Java Platform SE 7 )" . docs.oracle.com .
  12. https://web.archive.org/web/20110303225354/http://weblogs.java.net/blog/2006/05/04/understanding-weak-references أمثلة جافا
  13. "PHP: WeakReference - Manual" . www.php.net . تم الاطلاع عليه بتاريخ 9 يوليو 2025 .
  14. "weakref — المراجع الضعيفة" . وثائق بايثون . تم الاطلاع عليه بتاريخ 9 يوليو 2025 .
  15. "4.9. المراجع الضعيفة - وثائق فالا" . docs.vala.dev . تم الاطلاع عليه في 9 يوليو 2025 .

لغة سي++

جافا

PHP

بايثون