سؤال

لدينا تطبيق كبيرة ومعقدة نوعا ما مكتوب بلغة جافا الذي يعمل على رأس مجموعة Gridgain. المشكلة أواجه هو أن هذا التطبيق سوف يجلس هناك طلبات معالجة ما يقرب من يوم قبل أن يبدأ كل طلب مما أدى إلى استثناء من نوع java.nio.channels.ClosedByInterruptException.

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

package com.vlc.edge;

import com.vlc.common.VlcRuntimeException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;

public final class BufferedReaderImpl implements BufferedReader {
    private java.io.BufferedReader reader;

    public BufferedReaderImpl(final String source) {
        this(new File(source));
    }

    public BufferedReaderImpl(final File source) {
        try {
            reader = new java.io.BufferedReader(new FileReader(source));
        } catch (FileNotFoundException e) {
            throw new VlcRuntimeException(e);
        }
    }

    public BufferedReaderImpl(final Reader reader) {
        this.reader = new java.io.BufferedReader(reader);
    }

    public String readLine() {
        try {
            return reader.readLine();
        } catch (IOException e) {
            throw new VlcRuntimeException(e);
        }
    }

    public void close() {
        try {
            reader.close();
        } catch (IOException e) {
            throw new VlcRuntimeException(e);
        }
    }
}

وأعتقد أن المشكلة هي أن هذا التصميم لا يعفي صراحة التعامل مع الملف، الحل المقترح بلدي هو إضافة طريقة وضع الصيغة النهائية مثل هذا

    protected void finalize() throws Throwable
    {
        reader.close();
        super.finalize();   
    }

والتي سوف تفعل ذلك صراحة. السؤال (أخيرا) هو ما إذا كان أو لم يكن هذا من المرجح أن يكون له أي تأثير. هل الطبقات مثل java.io.BufferedReader لديها بالفعل بعض آلية للتعامل مع هذا النوع من المشاكل؟

وتحرير: أيضا تقدير كبير هنا سيكون طرق للتحقق ما إذا كان هذا هو في الواقع المشكلة ... أي هل هناك طريقة الاستعلام JVM تشغيل ويسأل عن انها مخصصات التعامل مع ملف

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

المحلول

وهناك نقطة صغيرة في finalize() الغلابة. إذا المقبض هو الحصول على تجميع البيانات المهملة وانتهت، ثم حتى لا مثيل java.io.BufferedReader، وسوف تحصل مغلقة.

ومن الممكن (وفقا لمواصفات) أن التعامل يتم تجميع البيانات المهملة ولكن لم تنته، ولكن هذا ليس من المرجح جدا.

هل يمكن أن حاول استخدام PhantomReferences لتنظيف مؤشرات الملفات غير المستخدمة، ولكن تخميني هو أن مثيلات BufferedReaderImpl لا تزال المشار إليه من مكان ما (على سبيل المثال القيم في Map من أسماء لفتح مقابض)، وهذا ما يمنعهم من كونها مغلقة (التي سوف أدوات الإنهاء القضية لن يساعد.)

نصائح أخرى

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

InputStream in = null;
try {
  in = ...;
  // do stuff
} catch (IOException e) {
  // error
} finally {
  if (in != null) { try { in.close(); } catch (Exception e) { } }
  in = null;
}

وقد تحتاج إلى التفاف هذه المقابض داخل الطبقة ولكن هذا ليس نهجا قويا.

ومواصفات جاوة تقول أنه لا يضمن أن 'finalize() "سيعدم. التعليمات البرمجية يجب FileReader صراحة على مقربة نفسك.

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