سؤال

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

المحلول

من فهم المراجع الضعيفة, بقلم إيثان نيكولاس:

مراجع ضعيفة

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

WeakReference weakWidget = new WeakReference(widget);

وبعد ذلك في مكان آخر في التعليمات البرمجية يمكنك استخدامه weakWidget.get() للحصول على الفعلي Widget هدف.طبعا الضعيف المرجع ليس قويا بما يكفي ل منع جمع القمامة ، لذلك يمكنك البحث (إذا لم يكن هناك قوي إشارات إلى القطعة) التي weakWidget.get() يبدأ فجأة العوده null.

...

المراجع الناعمة

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

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

وأضاف بيتر كيسلر في تعليق:

يتعامل Sun JRE مع SoftReferences بشكل مختلف عن WeakReferences.نحاول الاحتفاظ بالكائن المشار إليه بواسطة SoftReference إذا لم يكن هناك ضغط على الذاكرة المتوفرة.تفصيل واحد:تختلف سياسة JRE "-client" و"-server":يحاول -client JRE إبقاء بصمتك صغيرة من خلال تفضيل مسح SoftReferences بدلاً من توسيع الكومة، بينما يحاول -server JRE الحفاظ على أدائك مرتفعًا من خلال تفضيل توسيع الكومة (إن أمكن) بدلاً من مسح SoftReferences.حجم واحد لا يناسب الجميع.

نصائح أخرى

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

وSoftReferences من ناحية أخرى جيدة للتخزين المؤقت، والموارد recreatable الخارجية كما GC يؤخر عادة تطهيرها. مكفول ذلك على الرغم من أن جميع يتم طرح سوف تحصل على تطهيرها قبل OutOfMemoryError SoftReferences، ولذلك نظريا لا يمكن أن يسبب OOME [*].

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

والآن ل[*]. الحفاظ على SoftReference لا يمكن أن يسبب OOME في حد ذاته. إذا من ناحية أخرى عن طريق الخطأ استخدام SoftReference لمهمة ويعني WeakReference لاستخدامها (أي، عليك أن تبقي المعلومات المرتبطة كائن بطريقة أو بأخرى المشار إليها بقوة، وتخلص منه عندما يحصل الكائن المرجعي مسح)، يمكنك تشغيل إلى OOME كما التعليمات البرمجية التي استطلاعات ReferenceQueue ويمكن أن يحدث يتجاهل الكائنات المرتبطة لا تعمل في الوقت المناسب الموضة.

وهكذا، يعتمد القرار على استخدام - إذا كنت التخزين المؤقت المعلومات التي أمر مكلف لبناء، ولكن ومع ذلك reconstructible من البيانات الأخرى، استخدام مراجع الناعمة - إذا كنت حفظ إشارة إلى مثيل الكنسي بعض البيانات، أو كنت تريد أن يكون إشارة إلى كائن بدون "امتلاك" انه (وبالتالي منع من أن يكون GC'd)، استخدم إشارة ضعيفة.

في جافا;بالترتيب من الأقوى إلى الأضعف، هناك:القوية والناعمة والضعيفة والوهمية

أ مرجع قوي هو مرجع عادي يحمي الكائن المشار إليه من التجميع بواسطة GC.أي.لا يتم جمع القمامة أبدًا.

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

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

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

مصدر

القياس: افترض أن JVM هي مملكة، والكائن هو ملك المملكة، وGC هو مهاجم المملكة الذي يحاول قتل الملك (الكائن).

  • عندما يكون الملك قوي, ، GC لا يستطيع قتله.
  • عندما يكون الملك ناعم, يهاجمه GC لكن الملك يحكم المملكة بالحماية حتى تتوفر الموارد.
  • عندما يكون الملك ضعيف, يهاجمه GC لكنه يحكم المملكة دون حماية.
  • عندما يكون الملك شبح, لقد قتله GC بالفعل ولكن الملك متاح عبر روحه.

مرجع ضعيف http://docs.Oracle.com/javase/1.5.0/docs/api/java/lang/ref/WeakReference.html

مبدأ: weak reference يرتبط بجمع القمامة.عادة، كائن وجود واحد أو أكثر reference لن تكون مؤهلة لجمع القمامة.
المبدأ أعلاه لا ينطبق عندما يكون كذلك weak reference.إذا كان للكائن مرجع ضعيف مع كائنات أخرى، فهو جاهز لجمع البيانات المهملة.

لننظر إلى المثال أدناه:لدينا Map مع الكائنات حيث يشير المفتاح إلى كائن.

import java.util.HashMap;   
public class Test {

    public static void main(String args[]) {
        HashMap<Employee, EmployeeVal> aMap = new 
                       HashMap<Employee, EmployeeVal>();

        Employee emp = new Employee("Vinoth");
        EmployeeVal val = new EmployeeVal("Programmer");

        aMap.put(emp, val);

        emp = null;

        System.gc();
        System.out.println("Size of Map" + aMap.size());

    }
}

الآن، أثناء تنفيذ البرنامج الذي قمنا به emp = null.ال Map إن الاحتفاظ بالمفتاح لا معنى له هنا كما هو null.في الحالة المذكورة أعلاه، لا يتم جمع البيانات المهملة.

WeakHashMap

WeakHashMap هو واحد حيث الإدخالات (key-to-value mappings) ستتم إزالتها عندما لا يكون من الممكن استردادها من Map.

اسمحوا لي أن أظهر المثال أعلاه نفسه مع WeakHashMap

import java.util.WeakHashMap;

public class Test {

    public static void main(String args[]) {
        WeakHashMap<Employee, EmployeeVal> aMap = 
                    new WeakHashMap<Employee, EmployeeVal>();

        Employee emp = new Employee("Vinoth");
        EmployeeVal val = new EmployeeVal("Programmer");

        aMap.put(emp, val);

        emp = null;

        System.gc();
        int count = 0;
        while (0 != aMap.size()) {
            ++count;
            System.gc();
        }
        System.out.println("Took " + count
                + " calls to System.gc() to result in weakHashMap size of : "
                + aMap.size());
    }
}

انتاج: أخذ 20 calls to System.gc() ليؤدي إلى aMap size ل :0.

WeakHashMap يحتوي فقط على مراجع ضعيفة للمفاتيح، وليست مراجع قوية كغيرها Map الطبقات.هناك مواقف يتعين عليك الاهتمام بها عندما تتم الإشارة بقوة إلى القيمة أو المفتاح على الرغم من أنك استخدمته WeakHashMap.يمكن تجنب ذلك عن طريق لف الكائن في ملف مرجع ضعيف.

import java.lang.ref.WeakReference;
import java.util.HashMap;

public class Test {

    public static void main(String args[]) {
        HashMap<Employee, EmployeeVal> map = 
                      new HashMap<Employee, EmployeeVal>();
        WeakReference<HashMap<Employee, EmployeeVal>> aMap = 
                       new WeakReference<HashMap<Employee, EmployeeVal>>(
                map);

        map = null;

        while (null != aMap.get()) {
            aMap.get().put(new Employee("Vinoth"),
                    new EmployeeVal("Programmer"));
            System.out.println("Size of aMap " + aMap.get().size());
            System.gc();
        }
        System.out.println("Its garbage collected");
    }
}

المراجع الناعمة.

Soft Reference أقوى قليلاً من ذلك المرجع الضعيف.يسمح المرجع المبسط بجمع البيانات المهملة، ولكنه يطلب من أداة تجميع البيانات المهملة مسحها فقط في حالة عدم وجود خيار آخر.

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

والفرق الوحيد بين مرجع لينة وإشارة ضعيفة هو أن

<اقتباس فقرة>   

وجامع القمامة يستخدم خوارزميات لتحديد ما إذا كان أو لم يكن ل   استعادة كائن يمكن الوصول إليه بهدوء، ولكن دائما يستعيد وضعيفة   الكائن قابلة للوصول.

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

الفرق الحقيقي الوحيد

لكل وثيقة, ، مراجع ضعيفة فضفاضة يجب يتم مسحها بواسطة GC قيد التشغيل.

لكل وثيقة, ، مراجع لينة فضفاضة يجب يتم مسحها قبل طرح OOM.

هذا هو الفرق الحقيقي الوحيد.كل شيء آخر ليس جزءا من العقد.(سأفترض أن أحدث المستندات تعاقدية.)

المراجع الناعمة مفيدة. تستخدم ذاكرة التخزين المؤقت الحساسة للذاكرة SoftReferences، وليس WeakReferences.


الوحيد سليم استخدام WeakReference هو مراقبة تشغيل GC.يمكنك القيام بذلك عن طريق إنشاء WeakReference جديد يخرج كائنه خارج النطاق على الفور، ثم حاول إخراجه من نطاق فارغ weak_ref.get().عندما يكون null, ، تعلم أنه بين هذه المدة، تم تشغيل GC.

أما بالنسبة لل غير صحيح باستخدام WeakReference، القائمة لا نهاية لها:

  • اختراق رديء لتنفيذ مرجع ناعم ذو أولوية 2 بحيث لا تضطر إلى كتابة واحد، حتى الآن لا يعمل كما هو متوقع لأنه سيتم مسح ذاكرة التخزين المؤقت كل تشغيل GC، حتى في حالة وجود ذاكرة احتياطية.يرى https://stackoverflow.com/a/3243242/632951 للفيلز.(علاوة على ذلك، ماذا لو كنت بحاجة إلى أكثر من مستويين من أولوية ذاكرة التخزين المؤقت؟لا تزال بحاجة إلى مكتبة حقيقية لذلك.)

  • اختراق رديء لربط البيانات بكائن من فئة موجودة، حتى الآن يقوم بإنشاء تسرب للذاكرة (OutOfMemoryError) عندما يقرر GC الخاص بك أخذ قسط من الراحة بعد إنشاء المراجع الضعيفة الخاصة بك.علاوة على ذلك، فهو أبعد من القبيح:النهج الأفضل هو استخدام الصفوف.

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

هذا شرط يمكن أن يكون مفيدًا للغاية في فهم المراجع القوية والضعيفة والوهمية.


لأعطيك ملخصا،

إذا كان لديك فقط مراجع ضعيفة إلى كائن (بدون مراجع قوية)، سيتم استعادة الكائن بواسطة GC في دورة GC التالية.

إذا كان لديك فقط المراجع الناعمة إلى كائن (بدون مراجع قوية)، فسيتم استعادة الكائن بواسطة GC فقط عند نفاد ذاكرة JVM.


لذلك يمكنك أن تقول ذلك، هناك مراجع قوية السلطة المطلقة (لا يمكن جمعها بواسطة GC أبدًا)

المراجع الناعمة هي قوي من المراجع الضعيفة (حيث يمكنهم الهروب من دورة GC حتى نفاد ذاكرة JVM)

المراجع الضعيفة هي حتى أقل قوة من المراجع الناعمة (حيث لا يمكنها الخروج من أي دورة GC وسيتم استعادتها إذا لم يكن للكائن مرجع قوي آخر).


تشبيه المطعم

  • النادل - جي سي
  • أنت - كائن في الكومة
  • منطقة / مساحة المطعم - مساحة الكومة
  • عميل جديد - كائن جديد يريد طاولة في المطعم

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

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

إذا كنت عميل ضعيف (مشابه للإشارة الضعيفة)، فيمكن للنادل، حسب إرادته، (في أي وقت) أن يطلب منك مغادرة المطعم: P

الأنواع الستة لحالات إمكانية الوصول إلى الكائنات في Java -

  1. قويكائنات يمكن الوصول إليها ly - GC سوف لن يجمع (استعادة الذاكرة التي احتلها) هذا النوع من الكائنات.هؤلاء هم يمكن الوصول إليه عبر العقدة الجذرية أو أي كائن آخر يمكن الوصول إليه بقوة (أي.عبر المتغيرات المحلية ومتغيرات الفئة ومتغيرات المثيل وما إلى ذلك)
  2. ناعمكائنات يمكن الوصول إليها ly - GC قد يحاول لجمع هذا النوع من الكائنات اعتمادًا على تنافس الذاكرة.يمكن الوصول إليها من الجذر عبر واحد أو أكثر كائنات مرجعية ناعمة
  3. ضعيفكائنات يمكن الوصول إليها ly - GC يجب جمع هذا النوع من الأشياء.هذه يمكن الوصول إليها من الجذر عبر واحد أو أكثر كائنات مرجعية ضعيفة
  4. قادر على القيامة الكائنات - يقوم GC بالفعل بتجميع هذه الكائنات.لكن وقد يعودون إلى إحدى الحالات: قوي/لين/ضعيف عن طريق تنفيذ بعض اللمسات النهائية
  5. شبحكائن يمكن الوصول إليه - GC هو بالفعل بصدد جمع هذه الكائنات وقرر عدم إمكانية إعادة إحيائه بواسطة أي أداة نهائية (إذا أعلن عن طريقة Finalize() نفسها، فسيتم تشغيل أداة الإنهاء الخاصة بها).يمكن الوصول إليها من الجذر عبر واحد أو أكثر الكائنات المرجعية الوهمية
  6. لا يمكن الوصول إليه الكائن - الكائن لا يمكن الوصول إليه بقوة، أو بهدوء، أو ضعف، ولا يمكن الوصول إليه بشكل وهمي، ولا يمكن إحياؤه.هذه الكائنات جاهزة للاستصلاح

لمزيد من التفاصيل: https://www.artima.com/insidejvm/ed2/gc16.html " ينهار

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

مرجع ضعيف:يتم جمع الكائنات التي يتم الرجوع إليها بشكل ضعيف في كل دورة GC (ثانوية أو كاملة).

مرجع ناعم:عندما يتم جمع الكائنات التي يتم الرجوع إليها بشكل بسيط فقط، يعتمد ذلك على:

  1. -XX: علامة SoftRefLRUPolicyMSPerMB=N (القيمة الافتراضية هي 1000، والمعروفة أيضًا باسم ثانية واحدة)

  2. مقدار الذاكرة الحرة في الكومة.

    مثال:

    • تحتوي الكومة على مساحة خالية تبلغ 10 ميجابايت (بعد GC الكاملة)؛
    • -XX:SoftRefLRUPolicyMSPerMB=1000

    ثم سيتم جمع الكائن الذي تتم الإشارة إليه بواسطة SoftReference فقط إذا كانت آخر مرة تم الوصول إليها فيها أكبر من 10 ثوانٍ.

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