سؤال

جاوة الفعالة تقول:

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

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

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

المحلول

اقرأ هذه مقالة - سلعة

المفتاح يأخذ Aways هو:

يمكنك التفكير في المراجع المباشرة كمراجع قوية لا تتطلب ترميزًا إضافيًا لإنشاء الكائن أو الوصول إليه. الأنواع الثلاثة المتبقية من المراجع هي فئات فرعية للفئة المرجعية الموجودة في حزمة java.lang.ref. يتم توفير المراجع اللينة من قبل فئة softreference ، والمراجع الضعيفة من قبل فئة الضعف ، والمراجع الوهمية من قبل الوهمية.

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

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

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

تليها قائمة DeflistModel التي لن نشرها لتجنب تشوش هذا الرد.

نصائح أخرى

لتوضيح المفهوم مع مثال سريع (خام) ، فكر فيما يلي:

public interface ChangeHandler {
    public void handleChange();
}

public class FileMonitor {

    private File file;
    private Set<ChangeHandler> handlers = new HashSet<ChangeHandler>();

    public FileMonitor(File file) { 
        this.file = file;
    }

    public void registerChangeHandler(ChangeHandler handler) {
        this.handlers.add(handler);
    } 

    public void unregisterChangeHandler(ChangeHandler handler) {
        this.handlers.remove(handler);
    }

    ...
}

إذا كان فئة العميل يستخدم هذا FileMonitor API ، قد يفعلون هذا:

public class MyClass {

    File myFile = new File(...);
    FileMonitor monitor = new FileMonitor(myFile);

    public void something() {
        ...
        ChangeHandler myHandler = getChangeHandler();
        monitor.registerChangeHandler(myHandler);
        ...
    }
}

إذا كان مؤلف MyClass ثم ينسى الاتصال unregisterChangeHandler() عندما يتم ذلك مع المعالج ، FileMonitorHashSet سيشير إلى الأبد إلى المثيل الذي تم تسجيله ، مما تسبب في البقاء في الذاكرة حتى FileMonitor تم تدميره أو إنهاء التطبيق.

لمنع ذلك ، تقترح Bloch استخدام مجموعة ضعف مرجعية بدلاً من HashSet, ، بحيث إذا كان مثيلك MyClass تم تدميره ، وسيتم إزالة المرجع من مجموعة الشاشة.

يمكنك استبدال HashSet في FileMonitor مع WeakHashMap واستخدم المعالجات كمفاتيح ، لأن الأخير سيقوم تلقائيًا بإزالة المعالج من المجموعة عندما تختفي جميع الإشارات الأخرى إلى الكائن.

هنا قد تجد واضحة و عملي تفسير كذلك:تسرب الذاكرة في Android - تحديد وعلاج وتجنب

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