هل يتم تعيين كائنات للقيمة الخالية في Java قم بتجميع البيانات المهملة؟


Answers

في تجربتي ، في أكثر الأحيان ، يبطل الناس الإشارات من جنون الارتياب ليس بالضرورة. هنا دليل سريع:

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

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

أود أن أقول إن الغالبية العظمى من الوقت لن تحتاج إلى إلغاء المراجع. محاولة التفوق على جامع القمامة غير مجدية. سوف ينتهي بك الأمر برمز غير فعّال وغير قابل للقراءة.

Question

هل يؤدي تعيين مرجع كائن غير مستخدم إلى قيمة null في Java إلى تحسين عملية تجميع البيانات المهملة بأي طريقة قابلة للقياس؟

لقد علمتني تجربتي مع Java (و C #) أنه غالبًا ما يكون غير بديهي لمحاولة التغلب على الجهاز الظاهري أو مترجم JIT ، ولكني رأيت زملاء العمل يستخدمون هذه الطريقة وأنا أشعر بالفضول إذا كانت هذه ممارسة جيدة لاختيار يصل أو واحد من تلك الخرافات البرمجة الفودو؟




أفترض أن OP يشير إلى أشياء مثل هذه:

private void Blah()
{
    MyObj a;
    MyObj b;

    try {
        a = new MyObj();
        b = new MyObj;

        // do real work
    } finally {
        a = null;
        b = null;
    }
}

في هذه الحالة ، ألن يضع VM علامة عليها لـ GC بمجرد تركها على أية حال؟

أو ، من منظور آخر ، من شأنه أن يضع العناصر بشكل صريح ليجعلهم يحصلون على GC قبل أن يفعلوا إذا خرجوا من نطاقهم؟ إذا كان الأمر كذلك ، فقد يمضي VM وقت GC 'الكائن عندما لا تكون هناك حاجة للذاكرة على أي حال ، مما قد يتسبب في الواقع في أسوأ استخدام للأداة CPU لأنه سيكون GC أكثر.




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

لذلك يعتمد على ما تفعله ...




هذا يعتمد.

بصفة عامة ، أقصر ، يمكنك الاحتفاظ بالمراجع الخاصة بك ، وسرعان ما يتم جمعها.

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

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




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

بشكل عام ، يمكنك تعيين المراجع إلى قيمة خالية ، يعني القراءة للكود الذي تم إنجازه مع هذا الكائن تمامًا ولا ينبغي أن يساوره القلق بعد الآن.

يمكن تحقيق تأثير مماثل من خلال وضع مجموعة إضافية من الأقواس

{
  int l;
  {
    String bigThing = ....;
    l = bigThing.length();
  }
  ---
}

هذا يسمح لل bigThing أن يتم جمع القمامة مباشرة بعد ترك الأقواس المتداخلة.




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

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






Links