سؤال

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

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

المحلول

<اقتباس فقرة>   

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

     

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

فهم المراجع ضعف ، إيثان نيكولاس

نصائح أخرى

أحد الفروق التي يجب توضيحها هو الفرق بين أ WeakReference و أ SoftReference.

في الأساس أ WeakReference سيتم الحصول على GC-d بواسطة JVM بفارغ الصبر، بمجرد عدم وجود الكائن المشار إليه صعب إشارات إليها.أ SoftReferenced من ناحية أخرى، سوف يميل إلى تركه بواسطة أداة تجميع البيانات المهملة حتى يحتاج حقًا إلى استعادة الذاكرة.

مخبأ حيث قيم تقام في الداخل WeakReferences سيكون عديم الفائدة إلى حد كبير (في a WeakHashMap, ، فهي المفاتيح التي ضعف مرجعها). SoftReferences من المفيد التفاف القيم عندما تريد تنفيذ ذاكرة تخزين مؤقت يمكن أن تنمو وتتقلص مع الذاكرة المتوفرة

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

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

وكان علي أن أفعل هذا لإضافة بعض البيانات إلى java.awt.Component للالتفاف تغيير في JRE بين 1.4.2 و 1.5، ويمكن أن يكون ثابت من قبل إن شاء subclasses ترث كل مكون كنت مهتما الباحث (JButton، JFrame، JPanel .. ..) ولكن هذا كان أسهل بكثير مع رمز أقل من ذلك بكثير.

حالة أخرى مفيدة ل WeakHashMap و WeakReference هو تنفيذ تسجيل المستمع.

عندما تقوم بإنشاء شيء يريد الاستماع إلى أحداث معينة، عادةً ما تقوم بتسجيل مستمع، على سبيل المثال.

manager.registerListener(myListenerImpl);

إذا manager يخزن المستمع الخاص بك مع WeakReference, ، هذا يعني أنك لست بحاجة إلى إزالة السجل على سبيل المثال.مع manager.removeListener(myListenerImpl) لأنه ستتم إزالته تلقائيًا بمجرد عدم توفر المستمع أو المكون الخاص بك الذي يحمل المستمع.

بالطبع لا يزال بإمكانك إزالة المستمع يدويًا، لكن إذا لم تقم بذلك أو نسيته، فلن يتسبب ذلك في تسرب الذاكرة، ولن يمنع جمع القمامة من مستمعك.

أين WeakHashMap تأتي في الصورة؟

سجل المستمع الذي يرغب في تخزين المستمعين المسجلين باسم WeakReferenceيحتاج s إلى مجموعة لتخزين هذه المراجع.لا يوجد WeakHashSet التنفيذ في مكتبة Java القياسية فقط أ WeakHashMap ولكن يمكننا بسهولة استخدام الأخير "لتنفيذ" وظيفة الأول:

Set<ListenerType> listenerSet =
    Collections.newSetFromMap(new WeakHashMap<ListenerType, Boolean>());

مع هذا listenerSet لتسجيل مستمع جديد، عليك فقط إضافته إلى المجموعة، وحتى إذا لم تتم إزالته بشكل صريح، إذا لم يعد المستمع مرجعًا، فستتم إزالته تلقائيًا بواسطة JVM.

يوضح منشور المدونة هذا استخدام كلا الفئتين: جافا:المزامنة على معرف.الاستخدام يذهب شيء من هذا القبيل:

private static IdMutexProvider MUTEX_PROVIDER = new IdMutexProvider();

public void performTask(String resourceId) {
    IdMutexProvider.Mutex mutext = MUTEX_PROVIDER.getMutex(resourceId);
    synchronized (mutext) {
        // look up the resource and do something with it
    }
}

يوفر IdMutextProvider كائنات قائمة على المعرف للمزامنة.المتطلبات هي:

  • يجب إرجاع مرجع إلى نفس الكائن للاستخدام المتزامن للمعرفات المكافئة
  • يجب إرجاع كائن مختلف لمعرفات مختلفة
  • لا توجد آلية تحرير (لا يتم إرجاع الكائنات إلى الموفر)
  • يجب عدم التسرب (الكائنات غير المستخدمة مؤهلة لجمع البيانات المهملة)

يتم تحقيق ذلك باستخدام خريطة تخزين داخلية من النوع:

WeakHashMap<Mutex, WeakReference<Mutex>>

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

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

والآن إذا كان شخص ما يمكن أن يفسر الوهمية المراجع لي، وسأكون سعيدا ...

وكما ذكر أعلاه، وتعقد إشارة ضعيفة لطالما وجود مرجع قوية.

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

وبينما كان يلعب مع المستمعين على النحو المبين أعلاه أدركنا بسرعة أن الأجسام الحصول على جمع "فورا" من وجهة نظر المستخدم من عرض.

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

لقد قمت بالبحث عن كود Google عن "new WeakHashMap ()".

لقد حصلت على مجموعة من المطابقات من مشروع GNU classpath و

  1. مشروع اباتشي xbean: WeakHashMapEditor.java
  2. مشروع أباتشي لوسين : CachingWrapperFilter.java

ويمكنك استخدام weakhashmap لتنفيذ التخزين المؤقت خالية من الموارد لإنشاء كائن توسعية.

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

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