سؤال

أحصل على الخطأ التالي عند تنفيذ برنامج متعدد الخيوط

java.lang.OutOfMemoryError: Java heap space

حدث الخطأ أعلاه في أحد المواضيع.

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

  2. هل هناك أي طريقة لزيادة مساحة الكومة؟

  3. ما هي التغييرات التي يجب أن أجريها على برنامجي بحيث تحصل على مساحة أقل من الكومة؟

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

المحلول

إذا كنت ترغب في زيادة مساحة الكومة الخاصة بك ، فيمكنك الاستخدام java -Xms<initial heap size> -Xmx<maximum heap size> على سطر الأوامر. بشكل افتراضي ، تعتمد القيم على إصدار JRE وتكوين النظام. يمكنك معرفة المزيد عن خيارات VM على موقع Java.

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

نصائح أخرى

1.- نعم ، لكنه يشير إلى حد كبير إلى الذاكرة بأكملها المستخدمة من قبل البرنامج.

2.- نعم انظر خيارات Java VM

-Xms<size>        set initial Java heap size
-Xmx<size>        set maximum Java heap size

بمعنى آخر

java -Xmx2g تعيين 2 جيجابت من ذاكرة الوصول العشوائي كحد أقصى لتطبيقك

ولكن يجب أن ترى ما إذا لم يكن لديك تسرب ذاكرة أولاً.

3.- يعتمد على البرنامج. جرب تسربات الذاكرة الفورية. هذا السؤال سيكون من الصعب الإجابة عليه. في الآونة الأخيرة ، يمكنك ملف تعريف باستخدام JConsole لمحاولة معرفة أين ستذهب ذاكرتك

قد ترغب في إلقاء نظرة على هذا الموقع لمعرفة المزيد عن الذاكرة في JVM:http://developer.streamezzo.com/content/learn/articles/optimization-heap-memory-use

لقد وجدت أنه من المفيد الاستخدام VisualGC لمشاهدة كيفية ملء الأجزاء المختلفة من نموذج الذاكرة ، لتحديد ما يجب تغييره.

من الصعب تحديد أي جزء من الذاكرة تم ملؤه ، وبالتالي VisualGC ، حيث قد ترغب في تغيير الجزء الذي يواجه مشكلة ، بدلاً من مجرد القول ،

بخير! سأعطي 1G من ذاكرة الوصول العشوائي إلى JVM.

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

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

لزيادة حجم الكومة ، يمكنك استخدام وسيطة -xmx عند بدء تشغيل Java ؛ على سبيل المثال

-Xmx256M

يمكنك الحصول على حجم ذاكرة الكومة الخاص بك من خلال Programe.

public class GetHeapSize {
    public static void main(String[] args) {
        long heapsize = Runtime.getRuntime().totalMemory();
        System.out.println("heapsize is :: " + heapsize);
    }
} 

ثم يمكنك زيادة حجم الكومة أيضًا باستخدام: Java -xmx2ghttp://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html

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

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

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

  1. هل هناك أي طريقة لزيادة مساحة الكومة؟

نعم. ألق نظرة على هذا أوراكل مقالة - سلعة لمزيد من التفاصيل.

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

-xms:, ، الذي يحدد حجم الكومة الأولي والحد الأدنى

-xmx:, ، الذي يحدد الحد الأقصى لحجم الكومة

  1. ما هي التغييرات التي يجب أن أجريها على برنامجي بحيث تحصل على مساحة أقل من الكومة؟

ذلك يعتمد على طلبك.

  1. اضبط الحد الأقصى لذاكرة الكومة وفقًا لمتطلبات التطبيق الخاصة بك

  2. لا تسبب تسريبات الذاكرة في تطبيقك

  3. إذا وجدت تسريبات الذاكرة في التطبيق الخاص بك ، فابحث عن السبب الجذري بمساعدة أدوات التنميط مثل حصيرة, VIST VM , jconsole وما إلى ذلك بمجرد العثور على السبب الجذري ، قم بإصلاح التسريبات.

ملاحظات مهمة من أوراكل مقالة - سلعة

السبب: تشير رسالة Java Chep للرسالة التفصيلية إلى أنه لا يمكن تخصيص الكائن في كومة Java. هذا الخطأ لا يعني بالضرورة تسرب الذاكرة.

أسباب محتملة:

  1. التكوين غير لائق (عدم تخصيص ذاكرة كافية)
  2. ينقل التطبيق عن غير قصد إشارات إلى الكائنات وهذا يمنع الكائنات من جمع القمامة
  3. التطبيقات التي تستفيد المفرط للنهائيات. إذا كان لدى الفصل طريقة اللمسات الأخيرة ، فإن الكائنات من هذا النوع لا يتم استصلاح المساحة الخاصة بهم في وقت جمع القمامة. إذا لم يتمكن مؤشر ترابط Finalizer من الاستمرار ، مع قائمة انتظار الانتهاء ، يمكن أن تملأ كومة Java وسيتم إلقاء هذا النوع من استثناء OutofMemoryerror.

في ملاحظة مختلفة ، استخدم خوارزميات جمع القمامة الأفضل ( CMS أو G1GC)

الق نظرة على هذا سؤال لفهم G1GC

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

    الوقاية خير من العلاج. "لا تنشئ كائنات غير ضرورية"

  1. تقع المتغيرات المحلية على المكدس. مساحة الكومة تشغلها الأشياء.

  2. يمكنك استعمال ال -Xmx اختيار.

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

لا ، أعتقد أنك تفكر في مساحة المكدس. مساحة الكومة تشغلها الأشياء. الطريقة لزيادةها هي -xmx256m ، لتحل محل 256 بالمبلغ الذي تحتاجه على سطر الأوامر.

في NetBeans ، انتقل إلى شريط أدوات "Run" ،-> "تعيين تكوين المشروع"-> "تخصيص"-> "تشغيل" من Windo-> "VM Option"-> املأ "-xms2048m -xmx2048m '. يمكن أن يحل مشكلة حجم الكومة.

لتجنب هذا الاستثناء ، إذا كنت تستخدم Junit و SPRING ، فحاول إضافة هذا في كل فئة اختبار:

@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top