لا GC تضمن مسح الإشارات enqueued إلى ReferenceQueue في الطوبوغرافية النظام ؟

StackOverflow https://stackoverflow.com/questions/2497014

سؤال

نقول أن هناك اثنين من الأشياء ، A و B, و هناك مؤشر A.x --> B, ونحن إنشاء أقول ، WeakReferences إلى كل من A و B, مع المرتبطة بها ReferenceQueue.

نفترض أن كلا من A و B تصبح غير قابلة للوصول.حدسي B لا يمكن أن تعتبر غير قابلة للوصول من قبل A هو.في مثل هذه الحالة, هل نحن بطريقة أو بأخرى الحصول على ضمان أن كل المراجع سوف يكون enqueued في بديهية (الطوبوغرافية عندما لا يكون هناك دورات) في ReferenceQueue?أولا-هاء.المرجع(أ) قبل المرجع(ب).أنا لا أعرف ما إذا كان GC ملحوظ مجموعة من الكائنات غير قابلة للوصول ، ثم enqueued لهم في أي ترتيب معين?

كنت أراجع Finalizer.java الجوافة, رؤية هذا مقتطف:

private void cleanUp(Reference<?> reference) throws ShutDown {
  ...
  if (reference == frqReference) {
    /*
     * The client no longer has a reference to the
     * FinalizableReferenceQueue. We can stop.
     */
    throw new ShutDown();
  }

frqReference هو PhantomReference إلى استخدامها ReferenceQueue, حتى إذا كان هذا هو GC رائد لا Finalizable{ضعيفة, لينة, الوهمية}المراجع أن يكون على قيد الحياة ، لأنها مرجع الانتظار.لذا يجب أن تكون GC ماتت قبل طابور نفسها يمكن أن تكون GC رائد - ولكن لا يزال لا يمكن ضمان أن هذه الإشارات سوف يكون enqueued إلى ReferenceQueue في الترتيب الذي تحصل على "البيانات المهملة" (كما لو أنها تحصل GC ماتت واحدة قبل واحدة) ؟ رمز يعني أن هناك نوع من الضمان ، وإلا المجهزة المراجع يمكن من الناحية النظرية لا تزال في قائمة الانتظار.

شكرا

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

المحلول

لا يوجد ضمان طلب. في حالة Finalizer.java ، يمكن إيقاف مؤشر الترابط قبل معالجة جميع المراجع. انظر المستندات لـ FinalizablereferenceQueue:

  • الحفاظ على إشارة قوية إلى هذا الكائن حتى جميع المرتبطة

  • تم الانتهاء من المراجع. إذا تم جمع هذا الكائن في وقت سابق ،
  • لن يستدعي مؤشر ترابط الدعم {code finizereferent ()} على
  • المراجع المتبقية.

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

نصائح أخرى

أنا متأكد من أن الجواب لا.

تقول مواصفات JVM عن أساليب النهائيات:

لا يفرض جهاز Java Virtual أي طلب على مكالمات طريقة اللمسات الأخيرة. قد يتم استدعاء النهائيات بأي ترتيب أو حتى بشكل متزامن. ((JVM Spec 2.17.7)

من هذا استنتج أنه لا توجد ضمانات بأن المراجع في قائمة الانتظار بالترتيب الطوبولوجي.

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

أما بالنسبة Finalizer, يبدو أنه من المفترض أن يتم استخدامها من خلال FinalizableReferenceQueue المثال الوحيد الذي يفعل بعض classloader ذات الصلة السحر.على Finalizer يستخدم مرافقها الخاصة للكشف عن عندما FinalizableReferenceQueue من الذي وظيفيا يعتمد يصبح نفسها إليه;هذه هي النقطة عندما الخيط الذي يمتد Finalizer يعلم أنه يجب الخروج.من ما أفهم إذا كان التطبيق يتيح GC استعادة FRQ ، ثم finalizer موضوع الخروج ، أي إشارات enqueued "بعد" FRQ المرجعية لا يمكن معالجتها.هذا يعتمد على الطوبوغرافية النظام أو عدمه, ولكن أنا لا يمكن أن تقرر ما إذا كان هذا هو مشكلة أم لا.أعتقد أن التطبيق ليس من المفترض أن إسقاط FRQ طالما تجهيز المستصلحة الكائنات المشار إليها هو المهم.

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