java.lang.OutOfMemoryError: GC overhead limit exceeded [duplikat]

to pytanie ma już odpowiedzi tutaj : Błąd Javy.lang.OutOfMemoryError: GC overhead limit exceeded (20 odpowiedzi) Zamknięty 1 rok temu.

Dostaję ten błąd w programie, który tworzy kilka (setki tysięcy) obiektów Hashmapowych z kilkoma (15-20) wpisami tekstowymi każdy. Wszystkie te ciągi muszą zostać zebrane (bez podziału na mniejsze ilości) przed przesłaniem ich do bazy danych.

Według Sun, błąd zdarza się " jeśli zbyt dużo czasu jest spędzony w Garbage collection: jeśli więcej niż 98% całkowitego czasu jest spędzony w garbage collection i mniej niż 2% sterty zostanie odzyskane, zostanie wyrzucony OutOfMemoryError.".

Najwyraźniej można użyć linii poleceń, aby przekazać argumenty do JVM dla

  • zwiększenie rozmiaru sterty, poprzez "- Xmx1024m " (lub więcej), lub
  • całkowite wyłączenie sprawdzania błędów poprzez "- XX: - UseGCOverheadLimit".

Pierwsze podejście działa dobrze, drugie kończy się w innej Javie.lang.OutOfMemoryError, tym razem o stercie.

Więc, pytanie: czy są jakieś programowa alternatywa dla tego, dla konkretnego przypadku użycia(np. kilka małych obiektów HashMap)? Jeśli na przykład użyję metody HashMap clear (), problem zniknie, ale tak samo jak dane przechowywane w Hashmapie! :-)

Problem jest również omawiany w pokrewnym temacie w StackOverflow.

Author: Community, 2011-04-30

16 answers

W zasadzie kończy ci się pamięć, aby proces przebiegał płynnie. Opcje, które przychodzą na myśl:

  1. Określ więcej pamięci, jak wspomniałeś, spróbuj czegoś pomiędzy, Jak -Xmx512m najpierw
  2. Praca z mniejszymi partiami obiektów HashMap do przetworzenia na raz, jeśli to możliwe
  3. Jeśli masz dużo duplikatów łańcuchów, użyj String.intern() na nich przed umieszczeniem ich w HashMap
  4. Użyj HashMap(int initialCapacity, float loadFactor) konstruktor do tuningu dla Twojego przypadku
 156
Author: WhiteFang34,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55

Następujące zadziałały dla mnie. Wystarczy dodać następujący fragment:

dexOptions {
        javaMaxHeapSize "4g"
}

Do twojego build.gradle:

android {
    compileSdkVersion 23
    buildToolsVersion '23.0.1'

    defaultConfig {
        applicationId "yourpackage"
        minSdkVersion 14
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"

        multiDexEnabled true
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    packagingOptions {

    }

    dexOptions {
        javaMaxHeapSize "4g"
    }
}
 60
Author: Mina Fawzy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-23 14:01:28

@takrl: domyślne ustawienie tej opcji to:

java -XX:+UseConcMarkSweepGC

Co oznacza, że ta opcja nie jest domyślnie aktywna. Więc kiedy mówisz, że użyłeś opcji "+XX:UseConcMarkSweepGC" Zakładam, że używałeś tej składni:

java -XX:+UseConcMarkSweepGC

Co oznacza, że wyraźnie aktywowałeś tę opcję. Dla poprawnej składni i domyślnych ustawień Java HotSpot VM Options @ this dokument

 42
Author: qupera,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-17 16:35:25

Dla przypomnienia, mieliśmy ten sam problem dzisiaj. Naprawiliśmy to używając tej opcji:

-XX:-UseConcMarkSweepGC

Najwyraźniej to zmodyfikowało strategię używaną do zbierania śmieci, co sprawiło, że problem zniknął.

 24
Author: takrl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-27 16:07:21

Hmmm... będziesz musiał:

  1. Całkowicie przemyśl swój algorytm i struktury danych, tak aby nie potrzebował wszystkich tych małych HashMaps.

  2. Utwórz fasadę, która pozwoli Ci przeglądać te Hashmapy w pamięci i z pamięci zgodnie z wymaganiami. Prosty LRU-cache może być tylko biletem.

  3. Up pamięci dostępnej dla JVM. W razie potrzeby nawet zakup większej ilości pamięci RAM może być najszybszym i najtańszym rozwiązaniem, jeśli masz zarządzanie maszyną to gospodarze tej bestii. Mimo to: generalnie nie jestem fanem rozwiązań "rzucaj więcej sprzętu w it", zwłaszcza jeśli alternatywne rozwiązanie algorytmiczne można wymyślić w rozsądnym terminie. Jeśli nadal rzucasz więcej sprzętu na każdy z tych problemów, wkrótce napotkasz prawo malejących zwrotów.

Co ty właściwie próbujesz zrobić? Podejrzewam, że jest lepsze podejście do twojego problemu.

 11
Author: corlettk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-27 15:08:37

Użyj alternatywnej implementacji HashMap ( Trove ). Standard Java HashMap ma > 12-krotne obciążenie pamięci. Szczegóły można przeczytać tutaj .

 10
Author: Denis Rozhnev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-17 17:19:25

Nie przechowuj całej struktury w pamięci, czekając na koniec.

Zapisywanie wyników pośrednich do tymczasowej tabeli w bazie danych zamiast HashMap - funkcjonalnie tabela bazy danych jest odpowiednikiem hashmapy, tzn. obie obsługują dostęp do danych z kluczem, ale tabela nie jest związana z pamięcią, więc użyj tabeli indeksowanej zamiast hashmapy.

Jeśli zrobione poprawnie, Twój algorytm nie powinien nawet zauważyć zmiany-poprawnie tutaj oznacza użycie klasy do reprezentować tabelę, nawet podając jej metodę put (key, value) I get (key), tak jak hashmap.

Gdy tabela pośrednia jest kompletna, Wygeneruj z niej wymagane instrukcje sql zamiast z pamięci.

 9
Author: Rodney P. Barbati,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-28 19:07:28

Kolektor równoległy rzuci OutOfMemoryError, jeśli zbyt dużo czasu zostanie spędzone na zbieraniu śmieci. W szczególności, jeśli więcej niż 98% całkowitego czasu zostanie spędzone na zbieraniu śmieci i mniej niż 2% sterty zostanie odzyskane, OutOfMemoryError zostanie wyrzucony. Ta funkcja została zaprojektowana tak, aby uniemożliwić działanie aplikacji przez dłuższy czas, a jednocześnie zrobić niewielki lub żaden postęp, ponieważ sterta jest zbyt mała. W razie potrzeby tę funkcję można wyłączyć, dodając opcję -XX:-UseGCOverheadLimit do polecenia Kolejka

 8
Author: user3405305,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-25 05:51:42

Jeśli tworzysz setki tysięcy map hashowych, prawdopodobnie używasz znacznie więcej niż faktycznie potrzebujesz; o ile nie pracujesz z dużymi plikami lub grafiką, przechowywanie prostych danych nie powinno przekraczać limitu pamięci Java.

Powinieneś spróbować przemyśleć swój algorytm. W tym przypadku zaoferowałbym więcej pomocy w tym temacie, ale nie mogę udzielić żadnych informacji, dopóki nie podasz więcej informacji o kontekście problemu.

 5
Author: RétroX,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-30 04:04:10

Jeśli posiadasz java8 i możesz użyć G1 Garbage Collector, Uruchom aplikację za pomocą:

 -XX:+UseG1GC -XX:+UseStringDeduplication

To mówi G1, aby znaleźć podobne Ciągi i zachować tylko jeden z nich w pamięci, a pozostałe są tylko wskaźnikiem do tego łańcucha w pamięci.

Jest to przydatne, gdy masz dużo powtarzających się ciągów. To rozwiązanie może działać lub nie i zależy od każdej aplikacji.

Więcej informacji on:
https://blog.codecentric.de/en/2014/08/string-deduplication-new-feature-java-8-update-20-2/ http://java-performance.info/java-string-deduplication/

 5
Author: George C,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-12 14:04:15

Napraw wycieki pamięci w aplikacji za pomocą narzędzi profilowych, takich jak eclipse MAT lub VisualVM

Z JDK 1.7.x lub nowszymi wersjami, użyj G1GC, który wydaje 10% na wywóz śmieci w przeciwieństwie do 2% w innych algorytmach GC.

Oprócz ustawienia pamięci sterty za pomocą -Xms1g -Xmx2g, Spróbuj '

-XX:+UseG1GC 
-XX:G1HeapRegionSize=n, 
-XX:MaxGCPauseMillis=m, 
-XX:ParallelGCThreads=n, 
-XX:ConcGCThreads=n`
[[4]} spójrz na artykuł oracle w celu dostrojenia tych parametrów.

Niektóre pytania związane z G1GC w SE:

Java 7 (JDK 7) garbage collection and documentation on G1

Java G1 garbage collection in production

Agresywna strategia śmieciarza

 3
Author: Ravindra babu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:50

Do tego użyj poniższego kodu w pliku aplikacji gradle pod zamknięciem Androida.

DexOptions { javaMaxHeapSize "4G" }

 3
Author: Abhinandan Chada,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-24 09:41:00

W przypadku błędu:

" Wewnętrzny błąd kompilatora: java.lang.OutOfMemoryError: GC overhead limit exceeded at java.lang.AbstractStringBuilder "

Zwiększ przestrzeń Javy do 2GB tzn. -Xmx2g.

 2
Author: bpb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-23 08:17:40

Musisz zwiększyć rozmiar pamięci w Jdeveloper przejdź do 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
)
and

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
 2
Author: shashi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-15 07:28:38

W moim przypadku rozwiązaniem było zwiększenie pamięci za pomocą opcji -Xmx.

Miałem plik 10g odczytany w Javie i za każdym razem miałem ten sam błąd. Stało się tak, gdy wartość w kolumnie RES w poleceniu top osiągnęła wartość ustawioną w opcji-Xmx. Następnie zwiększając pamięć za pomocą opcji -Xmx wszystko poszło dobrze.

Był jeszcze jeden punkt. Kiedy ustawiłem JAVA_OPTS lub CATALINA_OPTS na moim koncie użytkownika i ponownie zwiększyłem ilość pamięci, dostałem ten sam błąd. Wtedy Ja wypisał wartość tych zmiennych środowiskowych w moim kodzie, co dało mi inne wartości niż to, co ustawiłem. Powodem było to, że Tomcat był korzeniem tego procesu i ponieważ nie byłem su-doerem, poprosiłem administratora o zwiększenie pamięci w catalina.sh W Tomcat.
 1
Author: M. Mashaye,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-15 18:09:20

To pomogło mi pozbyć się tego błędu.Ta opcja wyłącza -XX: + DisableExplicitGC

 0
Author: kanaparthikiran,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-07 16:13:07