كيفية اكتشاف متى لم يعد يتم الرجوع إلى كائن ما

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

  •  03-07-2019
  •  | 
  •  

سؤال

هل هناك طريقة لإنشاء معالج تسجيل سيتم استدعاؤه بالضبط في الوقت الذي يتم فيه تحرير المرجع الأخير لكائن معين؟

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

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

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

المحلول

باختصار، لا.

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

نصائح أخرى

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

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

أعتقد أن WeakReference يفعل ما تريد.يتم وضع WeakReference في قائمة الانتظار بمجرد أن يكون الوصول إليها ضعيفًا (على سبيل المثال.لقد اختفت جميع المراجع القوية).

انظر هذا المقال بواسطة إيثان نيكولاس.

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

المشكلة هي، "كيف يمكنك تنفيذ ذلك، دون أن يكون هناك شيء يحمل إشارة إلى الكائن؟"

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

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

انظر إجابتي لماذا قد تقوم بتنفيذ اللمسات النهائية ()؟

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

أنت استطاع تجاوز finalize() في كائنك، ولكن هذا يمثل مشكلة لأسباب ذكرها الآخرون.

بالنسبة لمثالك المحدد، يمكنك إلقاء نظرة على استخدام شيء مثل File.deleteOnExit(), ، والذي سيؤدي إلى إزالة الملف بمجرد خروج الجهاز الافتراضي.

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