سؤال

لقد عثرت مؤخرًا على جزء من تعليمات Java البرمجية باستخدام WeakReferences - لم يسبق لي أن رأيتها منتشرة على الرغم من أنني صادفتها عندما تم تقديمها.هل هذا شيء يجب استخدامه بشكل روتيني أم فقط عندما يواجه الشخص مشاكل في الذاكرة؟إذا كان الأمر الأخير، فهل يمكن تعديلها وتحديثها بسهولة أم أن الكود يحتاج إلى إعادة هيكلة جادة؟هل يمكن لمبرمج Java (أو C#) العادي أن يتجاهلها بشكل عام؟

يحرر هل يمكن أن يحدث أي ضرر من خلال الاستخدام المفرط للحماس لـ WRs؟

هل كانت مفيدة؟

المحلول

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

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

مثال:إذا كان لدي مجموعة من كائنات Foo في تطبيقي، فقد أرغب في استخدام مجموعة للاحتفاظ بسجل مركزي لجميع كائنات Foo الموجودة حولي.ولكن، عندما تقوم أجزاء أخرى من تطبيقي بإزالة كائن Foo عن طريق حذف جميع المراجع إليه، لا أريد أن يحتفظ المرجع المتبقي الذي تحتفظ به مجموعتي لهذا الكائن بجمع البيانات المهملة!حقا أريد فقط أن تختفي من مجموعتي.هذا هو المكان الذي يمكنك فيه استخدام شيء مثل Weak Set (تحتوي Java على WeakHashMap) بدلاً من ذلك، والذي يستخدم مراجع ضعيفة لأعضائها بدلاً من المراجع "القوية".

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

نصائح أخرى

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

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

هل يمكن أن يحدث أي ضرر عن طريق الاستخدام المفرط في الحماية من WRS؟

نعم انها تستطيع.

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

مصدر القلق الثاني هو أن هناك نفقات تشغيلية غير مباشرة عند استخدام مراجع ضعيفة.التكاليف الواضحة هي تكاليف إنشاء مراجع ومكالمات ضعيفة get عليهم.التكلفة الأقل وضوحًا هي أنه يجب القيام بعمل إضافي كبير في كل مرة يتم فيها تشغيل GC.

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

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

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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top