سؤال

إذا اتصلت finalize() على كائن من رمز البرنامج الخاص بي، سوف JVM هل مازلت تقوم بتشغيل الطريقة مرة أخرى عندما يقوم جامع البيانات المهملة بمعالجة هذا الكائن؟

سيكون هذا مثالًا تقريبيًا:

MyObject m = new MyObject();

m.finalize();

m = null;

System.gc()

هل الدعوة الصريحة إلى finalize() اعمل ال JVMجامع البيانات المهملة لا يقوم بتشغيل finalize() الطريقة على الكائن m?

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

المحلول

وفقًا لبرنامج الاختبار البسيط هذا، سيستمر JVM في إجراء مكالمته لـ Finalize() حتى لو قمت باستدعائها صراحةً:

private static class Blah
{
  public void finalize() { System.out.println("finalizing!"); }
}

private static void f() throws Throwable
{
   Blah blah = new Blah();
   blah.finalize();
}

public static void main(String[] args) throws Throwable
{
    System.out.println("start");
    f();
    System.gc();
    System.out.println("done");
}

الإخراج هو:

يبدأ
وضع اللمسات الأخيرة!
وضع اللمسات الأخيرة!
منتهي

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

نصائح أخرى

يجب على المرء أن يفهم سير عمل جامع البيانات المهملة (GC) لفهم وظيفة الإنهاء.لن يؤدي استدعاء ‎.finalize()‎ إلى استدعاء أداة تجميع البيانات المهملة، أو استدعاء system.gc.في الواقع، ما سيساعد المبرمج على الانتهاء هو إعلان مرجع الكائن على أنه "غير مرجعي".

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

يقتبس:"بعد استدعاء طريقة الإنهاء لكائن ما، لن يتم اتخاذ أي إجراء آخر حتى يقرر جهاز Java الظاهري مرة أخرى أنه لم يعد هناك أي وسيلة يمكن من خلالها الوصول إلى هذا الكائن بواسطة أي مؤشر ترابط لم ينته بعد، بما في ذلك إمكانية الوصول إلى هذا الكائن إجراءات بواسطة كائنات أو فئات أخرى جاهزة للانتهاء منها، وعند هذه النقطة قد يتم التخلص من الكائن."من Java API Doc على java.Object.finalize();

للحصول على شرح مفصل، يمكنك أيضًا التحقق من: javabook.computerware

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

public void cleanUp() {
  .
  .
  .
}

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