التي API في جافا لاستخدام ملف القراءة أن يكون أفضل أداء ؟

StackOverflow https://stackoverflow.com/questions/1812565

سؤال

في مكان العمل, كانت لدينا الملفات مع أكثر من مليون الصفوف في الملف.على الرغم من ذاكرة الملقم أكثر من 10GB مع 8GB من أجل JVM أحيانا الملقم الحصول على شنق لبضع لحظات ويكبت المهام الأخرى.

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

التي API يجب أن تستخدم لقراءة الملفات للحصول على أداء أفضل?

الحق الآن أنا باستخدام BufferedReader(new FileReader(...)) قراءة هذه ملفات CSV.

العملية :كيف يمكنني قراءة الملف ؟

  1. لقد قرأت ملفات سطرا.
  2. كل خط له عدة أعمدة.استنادا إلى أنواع لا تحليل لها في المقابل(تكلفة العمود في ضعف ، زيارة عمود في كثافة الكلمات الرئيسية عمود في السلسلة, إلخ..).
  3. لقد دفع المحتوى المؤهل(زيارة > 0) في HashMap وأخيرا يوضح الخريطة في نهاية المهمة

التحديث

أفعل هذه القراءة من 30 أو 31 الملفات(شهر واحد) البيانات وتخزين مؤهلة في الخريطة.في وقت لاحق من هذا استخدام الخريطة للحصول على بعض الجناة في جداول مختلفة.ولذلك فإن القراءة يجب أن يتم تخزين هذه البيانات كما يجب.على الرغم من أنني قد بدلت HashMap جزء BerkeleyDB الآن ولكن المسألة في وقت قراءة الملف هو نفسه أو حتى أسوأ من ذلك.

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

المحلول

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

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

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

احتمال آخر أن يكون كمان مع جمع القمامة.لديك اثنين من الآليات:

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

  • كمان مع JVM القمامة جامع الخيارات.هذه تختلف بين JVMs ، ولكن java -X يجب أن تعطي لك بعض التلميحات.

تحديث: الواعدة النهج:

هل كنت حقا بحاجة إلى مجموعة البيانات بأكملها في الذاكرة في وقت واحد للتجهيز ؟

نصائح أخرى

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

باستخدام BufferedReader(new FileReader(...)) لن يسبب ذلك.

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

تحرير:اتفقنا على أن المشكلة عن المساحة المستخدمة لتمثيل محتوى الملف في الذاكرة.بديل ضخمة في الذاكرة hashtable هو العودة إلى القديم "نوع دمج نهج" كنا عند الكمبيوتر الذاكرة تقاس كيلوبايت.(أفترض أن معالجة يهيمن خطوة حيث كنت تفعل بحث مع مفاتيح ك للوصول المرتبطة الصف R.)

  1. إذا لزم الأمر ، preprocess كل من ملفات الإدخال بحيث يمكن فرزها على مفتاح K.

  2. استخدام فعال ملف نوعا ما فائدة كل نوع من ملفات الإدخال في النظام على ك.كنت ترغب في استخدام الأداة التي سوف تستخدم الكلاسيكية دمج خوارزمية الفرز.هذا سوف تقسيم كل ملف إلى قطع أصغر التي يمكن تخزينها في الذاكرة ، فرز قطع, تكتب لهم إلى الملفات المؤقتة ، ثم دمج فرز الملفات المؤقتة.UNIX / Linux sort الأداة المساعدة هو خيار جيد.

  3. قراءة فرز الملفات في موازاة ذلك, قراءة جميع الصفوف التي تتصل مع بعضها القيمة الرئيسية من جميع الملفات وتجهيزها ثم يخطو إلى المفتاح التالي القيمة.

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

حاول استخدام التالية vm الخيارات من أجل ضبط gc (كما تفعل بعض gc الطباعة):

-verbose:gc -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:+PrintGCDetails -XX:+PrintGCTimeStamps
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top