سؤال

أحصل على رسالة الخطأ هذه أثناء تنفيذ اختبارات Junit الخاصة بي:

java.lang.OutOfMemoryError: GC overhead limit exceeded

أنا أعرف ما OutOfMemoryError هل ، لكن ماذا يعني حد GC النفقات العامة؟ كيف يمكنني حل هذا؟

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

المحلول

تعني هذه الرسالة أنه لسبب ما ، يستغرق جامع القمامة قدرًا مفرطًا من الوقت (افتراضيًا 98 ٪ من وقت وحدة المعالجة المركزية للعملية) ويسترد القليل جدًا من الذاكرة في كل تشغيل (افتراضيًا 2 ٪ من الكومة).

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

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

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

الدفع هذه المقالة للحصول على التفاصيل (على وجه التحديد هذا الجزء).

نصائح أخرى

يلقي GC هذا الاستثناء عندما يتم قضاء الكثير من الوقت في مجموعة القمامة لعودة قليلة للغاية ، على سبيل المثال. يتم إنفاق 98 ٪ من وقت وحدة المعالجة المركزية على GC ويتم استرداد أقل من 2 ٪ من الكومة.

تم تصميم هذه الميزة لمنع التطبيقات من الركض لفترة طويلة من الزمن مع إحراز تقدم ضئيل أو معدوم لأن الكومة صغيرة جدًا.

يمكنك إيقاف تشغيل هذا مع خيار سطر الأوامر-XX:-UseGCOverheadLimit

مزيد من المعلومات هنا

تحرير: يبدو أن شخصًا ما يمكنه الكتابة بشكل أسرع مني :)

إذا كنت متأكدًا من أنه لا يوجد تسريبات الذاكرة في برنامجك ، حاول:

  1. زيادة حجم الكومة ، على سبيل المثال -Xmx1g.
  2. تمكين جامع التوقف المؤقت المتزامن -XX:+UseConcMarkSweepGC.
  3. أعد استخدام الكائنات الموجودة عندما يكون ذلك ممكنًا لحفظ بعض الذاكرة.

إذا لزم الأمر ، فحص الحد يمكن تعطيلها بإضافة الخيار -XX:-UseGCOverheadLimit إلى سطر الأوامر.

عادة ما يكون الرمز. هذا مثال بسيط:

import java.util.*;

public class GarbageCollector {

    public static void main(String... args) {

        System.out.printf("Testing...%n");
        List<Double> list = new ArrayList<Double>();
        for (int outer = 0; outer < 10000; outer++) {

            // list = new ArrayList<Double>(10000); // BAD
            // list = new ArrayList<Double>(); // WORSE
            list.clear(); // BETTER

            for (int inner = 0; inner < 10000; inner++) {
                list.add(Math.random());
            }

            if (outer % 1000 == 0) {
                System.out.printf("Outer loop at %d%n", outer);
            }

        }
        System.out.printf("Done.%n");
    }
}

باستخدام Java 1.6.0_24-B07 على Windows7 32 بت.

java -xloggc: gc.log garbagecollector

ثم انظر إلى gc.log

  • نشأ 444 مرة باستخدام طريقة سيئة
  • أدى 666 مرة باستخدام طريقة أسوأ
  • نشأ 354 مرة باستخدام طريقة أفضل

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

سبب ل خطأ

الحد الأدنى النفقات العامة لـ GC "يشير إلى أن جامع القمامة يعمل طوال الوقت وأن برنامج Java يحرز تقدماً بطيئًا للغاية.

بعد مجموعة القمامة ، إذا كان تنفق عملية Java أكثر من 98 ٪ تقريبًا من وقتها في جمع القمامة وإذا كان يتعافى أقل من 2 ٪ من الكومة وكان يعمل حتى الآن في مجموعات القمامة الخمسة الأخيرة (ثابتة الترجمة) على التوالي ، ثم أ java.lang.outofmemoryerror هذا خطئ

  1. زيادة حجم الكومة إذا كان الكومة الحالية لا يكفي.
  2. إذا كنت لا تزال تحصل على هذا الخطأ بعد زيادة ذاكرة الكومة ، استخدم الذاكرة أدوات التنميط مثل حصيرة (أداة محلل الذاكرة) ، VIST VM الخ وإصلاح تسرب الذاكرة.
  3. ترقية إصدار JDK إلى أحدث إصدار (1.8.x) أو ما لا يقل عن 1.7.x واستخدم خوارزمية G1GC. . هدف الإنتاجية لـ G1 GC هو وقت التطبيق بنسبة 90 في المائة و 10 في المائة من وقت جمع القمامة
  4. بصرف النظر عن وضع ذاكرة الكومة مع -Xms1g -Xmx2g ، محاولة

    -XX:+UseG1GC -XX:G1HeapRegionSize=n -XX:MaxGCPauseMillis=m  
    -XX:ParallelGCThreads=n -XX:ConcGCThreads=n
    

ألق نظرة على بعض الأسئلة ذات الصلة المتعلقة بخصوص G1GC

Java 7 (JDK 7) مجموعة القمامة والوثائق على G1

مجموعة القمامة Java G1 في الإنتاج

مقالة Oracle Technetwork لـ GC Finetuning

فقط قم بزيادة حجم الكومة قليلاً من خلال تحديد هذا الخيار في

تشغيل → قم بتشغيل التكوينات ← وسيطات → VM وسيطات

-Xms1024M -Xmx2048M

XMS - للحصول على الحد الأدنى

XMX - للحصول على الحد الأقصى

بالنسبة لي ، عملت الخطوات التالية:

  1. افتح ال eclipse.ini ملف
  2. يتغيرون

    -Xms40m
    -Xmx512m
    

    ل

    -Xms512m
    -Xmx1024m
    
  3. إعادة تشغيل الكسوف

انظر هنا

جرب هذا

افتح ال build.gradle ملف

  android {
        dexOptions {
           javaMaxHeapSize = "4g"
        }
   }

ما يلي عمل بالنسبة لي. فقط أضف المقتطف التالي:

android {
        compileSdkVersion 25
        buildToolsVersion '25.0.1'

defaultConfig {
        applicationId "yourpackage"
        minSdkVersion 10
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        multiDexEnabled true
    }
dexOptions {
        javaMaxHeapSize "4g"
    }
}

زيادة javamaxheapsize في ملف build.gradle (الوحدة النمطية: التطبيق)

dexOptions {
    javaMaxHeapSize "1g"
}

إلى (إضافة هذا الخط في Gradle)

 dexOptions {
        javaMaxHeapSize "4g"
    }

يمكنك أيضًا زيادة تخصيص الذاكرة وحجم الكومة عن طريق إضافة هذا إلى gradle.properties ملف:

org.gradle.jvmargs=-Xmx2048M -XX\:MaxHeapSize\=32g

لا يجب أن يكون 2048 مترًا و 32 جرامًا ، مما يجعله كبيرًا كما تريد.

تحتاج إلى زيادة حجم الذاكرة في JDeveloper اذهب إلى setdomainenv.cmd.

set WLS_HOME=%WL_HOME%\server    
set XMS_SUN_64BIT=**256**
set XMS_SUN_32BIT=**256**
set XMX_SUN_64BIT=**3072**
set XMX_SUN_32BIT=**3072**
set XMS_JROCKIT_64BIT=**256**
set XMS_JROCKIT_32BIT=**256**
set XMX_JROCKIT_64BIT=**1024**
set XMX_JROCKIT_32BIT=**1024**

if "%JAVA_VENDOR%"=="Sun" (
    set WLS_MEM_ARGS_64BIT=**-Xms256m -Xmx512m**
    set WLS_MEM_ARGS_32BIT=**-Xms256m -Xmx512m**
) else (
    set WLS_MEM_ARGS_64BIT=**-Xms512m -Xmx512m**
    set WLS_MEM_ARGS_32BIT=**-Xms512m -Xmx512m**
)

و

set MEM_PERM_SIZE_64BIT=-XX:PermSize=**256m**
set MEM_PERM_SIZE_32BIT=-XX:PermSize=**256m**

if "%JAVA_USE_64BIT%"=="true" (
    set MEM_PERM_SIZE=%MEM_PERM_SIZE_64BIT%
) else (
    set MEM_PERM_SIZE=%MEM_PERM_SIZE_32BIT%
)

set MEM_MAX_PERM_SIZE_64BIT=-XX:MaxPermSize=**1024m**
set MEM_MAX_PERM_SIZE_32BIT=-XX:MaxPermSize=**1024m**

أنا أعمل في Android Studio وواجهت هذا الخطأ عند محاولة إنشاء APK موقّع للإصدار. تمكنت من بناء واختبار تصحيح أخطاء APK دون أي مشكلة ، ولكن بمجرد أن أرغب في إنشاء إصدار APK ، سيتم تشغيل عملية الإنشاء لمدة دقائق متتالية ، ثم تنتهي أخيرًا مع "خطأ java.lang.outofmemoryror: GC تجاوز الحد العلوي ". لقد قمت بزيادة أحجام الكومة لكل من VM و Android Dex برنامج التحويل البرمجي ، لكن المشكلة استمرت. أخيرًا ، بعد عدة ساعات وأكواب قهوة ، اتضح أن المشكلة كانت في ملف "build.gradle" على مستوى التطبيق - كان لدي المعلمة "MinifyEnabled" لنوع بناء الإصدار إلى "False" ، وبالتالي تشغيل المواد البروغوارد على الرمز الذي لم يمر من خلال عملية تقسيم الكود (انظر https://developer.android.com/studio/build/shrink-code.html). لقد غيرت المعلمة "MinifyEnabled" إلى "True" وتم تنفيذ بناء الإصدار كحلم :)

باختصار ، اضطررت إلى تغيير ملف "build.gradle" على مستوى التطبيق من: // ...

buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        signingConfig signingConfigs.sign_config_release
    }
    debug {
        debuggable true
        signingConfig signingConfigs.sign_config_debug
    }
}

//...

ل

    //...

buildTypes {
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        signingConfig signingConfigs.sign_config_release
    }
    debug {
        debuggable true
        signingConfig signingConfigs.sign_config_debug
    }
}

//...

لزيادة حجم الكومة في فكرة Intellij اتبع التعليمات التالية. عملت معي.

لمستخدمي Windows ،

انتقل إلى الموقع حيث يتم تثبيت IDE والبحث عن المتابعة.

idea64.exe.vmoptions

تحرير الملف وإضافة ما يلي.

-Xms512m
-Xmx2024m
-XX:MaxPermSize=700m
-XX:ReservedCodeCacheSize=480m

هذا هو !!

إعادة تشغيل جهاز MacBook الخاص بي إصلاح هذه المشكلة بالنسبة لي.

في Netbeans ، قد يكون من المفيد تصميم حجم كومة أقصى. اذهب إلى يركض => تعيين تكوين المشروع => يعدل أو يكيف. في ال يركض من نافذتها ، انتقل إلى خيار VM, ، أملأ -Xms2048m -Xmx2048m. يمكن أن يحل مشكلة حجم الكومة.

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