سؤال

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

لذلك قمت بإنشاء InternPool<T> الفصل يسمح لي بالتدريب في كل فئة من الكائنات. داخليًا ، يستخدم المسبح أ WeakHashMap<T, WeakReference<T>>. فمثلا:

InternPool<BigDecimal> pool = new InternPool<BigDecimal>();

...

// Read BigDecimal from in buffer and then intern.
BigDecimal quantity = pool.intern(readBigDecimal(in));

سؤالي: أنا أستخدم InternPool إلى عن على BigDecimal ولكن هل يجب أن أفكر أيضًا في استخدامه String بدلاً من Stringintern() الطريقة التي أعتقد أنها تستخدم مساحة بيرجن؟ ما هي ميزة استخدام مساحة بيرجن؟

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

المحلول

من المحتمل أن JVM's String.intern() سيكون تجمع أسرع. afaik ، يتم تنفيذه في الكود الأصلي ، لذلك هو ينبغي كن أسرع واستخدم مساحة أقل من تجمع تم تنفيذه باستخدام WeakHashMap و WeakReference. ستحتاج إلى القيام ببعض القياس الدقيق لتأكيد ذلك.

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

نصائح أخرى

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

أيضا ، سأستخدم مجموعات جوجل MapMaker لخلق InternPool لتجنب إعادة إنشاء العجلة:

Map<BigDecimal,BigDecimal> bigDecimalPool = new MapMaker()
    .weakKeys()
    .weakValues()
    .expiration(1, TimeUnits.MINUTES)
    .makeComputingMap(
      new Function<BigDecimal, BigDecimal>() {
        public BigDecimal apply(BigDecimal value) {
          return value;
        }
      });

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

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