سؤال

أعلم أن هناك أ WeakHashMap في java.util, ، ولكن منذ أن يستخدم WeakReferences لكل شيء، والذي يشار إليه فقط بهذا Map, ، سوف تضيع الكائنات المشار إليها في دورة GC التالية.لذلك، يكون الأمر عديم الفائدة تقريبًا إذا كنت تريد تخزين بيانات عشوائية مؤقتًا، والتي من المحتمل جدًا أن يتم طلبها مرة أخرى دون أن تكون مرتبطة ارتباطًا وثيقًا بقية الوقت.الحل الأفضل هو الخريطة التي تستخدم SoftReferenceبدلاً من ذلك، لكنني لم أجد واحدة في حزمة Java RT.

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

المحلول

تحرير (أغسطس.2012):

اتضح أن الحل الأفضل حاليًا هو على الأرجح Guava 13.0 Cache الطبقات، وأوضح على الجوافة ويكي - وهذا ما سأستخدمه.حتى أنه يدعم بناء SoftHashMap (يرى CacheBuilder.newBuilder().softKeys())، ولكن من المحتمل ألا يكون هذا هو ما تريده، كما يوضح خبير Java جيريمي مانسون (ستجد الرابط أدناه).


ليس هذا أنا أعلم عن (نوفمبر.2008)، لكنك تجد بعض التنفيذ لـ SoftHashMap على الشبكة.

مثل هذه: SoftHashMap أو هذا.


تحرير (نوفمبر)2009)
مثل ماتياس يذكر في التعليقات، و جوجل الجوافة مصمم الخرائط يستخدم SoftReferences:

أ ConcurrentMap منشئ، وتوفير أي مجموعة من هذه الميزات:

  • مفاتيح ناعمة أو ضعيفة،
  • القيم الناعمة أو الضعيفة،
  • انتهاء الصلاحية في الوقت المناسب، و
  • حساب القيم عند الطلب.

كما ذكر في هذا الموضوع, ، مرشح JSR166y آخر:

jsr166y.ConcurrentReferenceHashMap

يوفر خريطة مرجعية متزامنة بديلة لتطبيق Google (والتي تعتمد على سلسلة رسائل خلفية لطرد الإدخالات)


تحرير (أغسطس 2012)

يستخدم تطبيق Google سلسلة محادثات في الخلفية فقط عندما يُطلب انتهاء صلاحية الإدخالات في الوقت المحدد.على وجه الخصوص، فإنه يستخدم ببساطة java.util.Timer, ، وهو ليس تطفليًا مثل وجود مؤشر ترابط منفصل في الخلفية.

يوصي جيريمي مانسون، لأي ذاكرة تخزين مؤقت، باستخدام هذه الميزة لتجنب مخاطر SoftReference:http://jeremymanson.blogspot.de/2009/07/how-hotspot-decides-to-clear_07.html

هناك تنفيذ آخر من أباتشي كومنز, ، يسمى org.apache.commons.collections.map.ReferenceMap;فهو لا يدعم الإزالة المحددة بوقت، ولكنه يدعم اختيار ما إذا كان ينبغي مقارنة المفاتيح حسب الهوية أو المساواة.علاوة على ذلك، فإن هذا التنفيذ ليس متزامنًا - يمكن جعله متزامنًا، لكن هذا يعمل بشكل أقل جودة عند الوصول من سلاسل رسائل متعددة.

نصائح أخرى

أنا على دراية بمكتبتين تقدمان تطبيق SoftHashMap:

  1. أباتشي كومنز:org.apache.commons.collections.map.ReferenceMap

  2. مجموعات جوجل:com.google.common.collect.ReferenceMap

وهناك تنفيذ المثال في 98 قضية من المتخصصين جافا النشرة

شيرو يأتي مع SoftHashMap مصممة للتخزين المؤقت. التي تقوم على هذه المادة المرسلة بواسطة JB أعلاه والمرخصة بموجب V2 أباتشي. يمكنك العثور على وثائق هنا وشفرة المصدر <أ href = على "HTTP : //shiro.apache.org/static/1.1.0/apidocs/src-html/org/apache/shiro/util/SoftHashMap.html "يختلط =" نوفولو "> هنا .

هل تعتبر باستخدام <لأ href = "https://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/map/LRUMap.html" يختلط = "نوفولو noreferrer "> LRUMap بدلا من ذلك من HashMap لينة؟ يمكنك الحصول على مزيد من السيطرة على ما يحصل المخزنة (أو على الأقل، كم).

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

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

Runtime.getRuntime().getFreeMemory();

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

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

ووsoftreferences هي وسيلة رائعة لخلق مخبأ growable. وبالتالي فإن الحل المثالي سيكون لاستخدام SoftHashMap ومعهم كمية منتظمة حجم ثابت. لديك كل إدراج في ذاكرة التخزين المؤقت الذهاب إلى كل من ذاكرة التخزين المؤقت الثابتة وخريطة التجزئة لينة ثم إلى مرجع شيء نرى إذا به في hashmap لينة (وتحديث الوقت إشارة في ذاكرة التخزين المؤقت). بهذه الطريقة فقط أهم البنود الخاصة بك (وفقا لالخاص LRU سياسة المختار، MFU، ...) لن يتم إزالة لأنها يتم الرجوع إليها بشدة في ذاكرة التخزين المؤقت ولكن سوف يعقد أيضا إلى المزيد من الأشياء (مع عدم وجود سياسة التحكم) طالما كما أن هناك ذاكرة كافية.

scroll top