Awaria kompilacji Maven Out of Memory

88

Na dzień dzisiejszy moja kompilacja Mavena kończy się niepowodzeniem.

[INFO] [ERROR] Unexpected
[INFO] java.lang.OutOfMemoryError: Java heap space
[INFO]  at java.util.Arrays.copyOfRange(Arrays.java:2694)
[INFO]  at java.lang.String.<init>(String.java:203)
[INFO]  at java.lang.String.substring(String.java:1877)

[ERROR] Brak pamięci; aby zwiększyć ilość pamięci, użyj flagi -Xmx podczas uruchamiania (java -Xmx128M ...)

Od wczoraj pomyślnie przeprowadziłem kompilację Mavena.

Na dzień dzisiejszy po prostu podskoczyłem do 3 GB . Poza tym zmieniłem tylko 2-3 drobne linie kodu, więc nie rozumiem tego błędu braku pamięci.

vagrant@dev:/vagrant/workspace$ echo $MAVEN_OPTS
-Xms1024m -Xmx3000m -Dmaven.surefire.debug=-Xmx3000m

EDYCJA: Próbowałem komentować posta, zmieniając plik pom.xml mojego uszkodzonego modułu. Ale mam ten sam błąd kompilacji Maven.

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
            <source>1.5</source>
            <target>1.5</target>
            <fork>true</fork>
            <meminitial>1024m</meminitial>
            <maxmem>2024m</maxmem>
       </configuration>
    </plugin>
Kevin Meredith
źródło
1
Czy mógłbyś podać więcej śladu stosu? Jestem ciekawy, co może powodować, że inicjalizacja String zabraknie pamięci. Ustawienie rozmiaru sterty w MAVEN_OPTS brzmi jak droga do zrobienia, ale przypuszczam, że gdzieś jest absurdalnie duży ciąg, na który możesz po prostu nie przydzielić wystarczająco dużo -Xmx.
Edward Samson,

Odpowiedzi:

136

O jakim rodzaju module „internetowym” mówisz? Czy jest to prosta wojna i czy wojna typu opakowania?

Jeśli nie korzystasz z zestawu narzędzi internetowych Google (GWT), nie musisz go dostarczać gwt.extraJvmArgs

Rozwidlenie procesu kompilacji może nie być najlepszym pomysłem, ponieważ rozpoczyna drugi proces, który MAVEN_OPTScałkowicie ignoruje , co utrudnia analizę.

Więc spróbuję zwiększyć Xmx, ustawiając MAVEN_OPTS

export MAVEN_OPTS="-Xmx3000m"

I nie rozwidlaj kompilatora do innego procesu

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <source>1.5</source>
        <target>1.5</target>
   </configuration>
</plugin>

Zwiększanie -XX:MaxPermSize=512mnie powinno być wymagane, ponieważ jeśli przyczyną problemu jest rozmiar perm, to spodziewałbym się błędujava.lang.OutOfMemoryError: PermGen space

Jeśli to nie rozwiąże problemu, możesz utworzyć zrzuty sterty do dalszej analizy, dodając -XX:+HeapDumpOnOutOfMemoryError. Dodatkowo możesz użyć jconsole.exe w swoim katalogu bin java, aby połączyć się z jvm podczas działania kompilacji i zobaczyć, co się dzieje w stercie jvm.

Kolejny pomysł (może być głupi), który do mnie przyszedł, czy masz wystarczająco dużo pamięci RAM w swoim komputerze? Definiowanie rozmiaru pamięci jest fajne, ale jeśli twój host ma tylko 4 GB, możesz mieć problem z tym, że Java nie jest w stanie użyć zdefiniowanej pamięci, ponieważ jest już używana przez system operacyjny, Javę, MS Office ...

vach
źródło
dzięki za odpowiedź. Czy twoja sugestia usunięcia rozwidlonej maszyny JVM dotyczy również wtyczki „maven-surefire-plugin”? Wypróbowałem twoją sugestię, aby zwiększyć moją pamięć MAVEN_OPTS do 3000. Mój kompilator maven nie miał ustawienia dla rozwidlonego JVM, więc nie musiałem tam niczego zmieniać. I tak, moja maszyna wirtualna gościa ma 4 GB pamięci RAM. Maszyna hosta ma 8 GB pamięci RAM.
Kevin Meredith
2
przy okazji, kompilacja mvn znowu zawiodła z twoimi sugestiami.
Kevin Meredith
1
Zwykle staram się unikać rozwidlenia procesów, o ile nie uruchamiam go. Jeśli Twój system ma tylko 4 GB, wówczas system operacyjny używa ~ 1 GB. Więc masz 3 GB odpoczynku. Jeśli maven zaczyna się od Xms = 1 GB, to reszta wolnej pamięci wynosi 2 GB. Następnie rozwidlenie kompilatora rozpoczęło się od Xms = 1 GB .... co zmniejsza ilość wolnej pamięci do 1 GB. Teraz możesz odjąć pamięć PermGen 128 MB, rozwidlony proces bezpiecznej wtyczki, ... Jak widać, ustawienia Xmx najprawdopodobniej nigdy nie mogłyby zostać użyte jako JVM, ponieważ pamięć jest prosta, a nie wolna. Czy próbowałeś używać JConsole? i HeapDumpOnOutOfMemoryError?
vach
Usunąłem Xms1024m z mojego MAVEN_OPTS, ale kompilacja mvn nadal się nie powiodła. Dodałem "HeapDump ..." do mojego MAVEN_OPTS, ale nie jestem pewien, gdzie zrzut zostanie wydrukowany. Zajmuję się teraz JConsole.
Kevin Meredith
Zrzuty są plcesami w katalogu
jvms
36

Odpowiadając późno, aby wspomnieć o innej opcji zamiast wspólnej MAVEN_OPTSzmiennej środowiskowej do przekazania do Mavena, zbuduj wymagane opcje JVM.

Od Maven 3.3.1 mógłbyś mieć .mvnfolder jako część danego projektu i jvm.configplik jako idealne miejsce na taką opcję.

dwa nowe opcjonalne pliki konfiguracyjne .mvn/jvm.configi .mvn/maven.config, znajdujące się w katalogu podstawowym drzewa źródłowego projektu. Jeśli są obecne, pliki te udostępnią domyślne opcje jvm i maven. Ponieważ te pliki są częścią drzewa źródłowego projektu, będą obecne we wszystkich wyewidencjonowanych projektach i będą automatycznie używane za każdym razem, gdy projekt jest budowany.

Jako część oficjalnych informacji o wydaniu

W Maven nie jest łatwo zdefiniować konfigurację JVM na podstawie projektu. Istniejący mechanizm oparty na zmiennej środowiskowej MAVEN_OPTSi jej zastosowaniu ${user.home}/.mavenrcjest inną opcją, której wadą jest brak bycia częścią projektu.

Począwszy od tej wersji, możesz zdefiniować konfigurację maszyny JVM za pomocą ${maven.projectBasedir}/.mvn/jvm.configpliku, co oznacza, że ​​możesz zdefiniować opcje kompilacji dla każdego projektu. Ten plik stanie się częścią Twojego projektu i zostanie wpisany wraz z Twoim projektem. Więc nie trzeba już za MAVEN_OPTS, .mavenrcplików. Na przykład, jeśli umieścisz w ${maven.projectBasedir}/.mvn/jvm.configpliku następujące opcje JVM :

-Xmx2048m -Xms1024m -XX:MaxPermSize=512m -Djava.awt.headless=true

Główną zaletą tego podejścia jest to, że konfiguracja jest odizolowana od danego projektu i zastosowana do całej kompilacji, a także mniej krucha niż w MAVEN_OPTSprzypadku innych programistów pracujących nad tym samym projektem (zapominając o ustawieniu).
Ponadto opcje zostaną zastosowane do wszystkich modułów w przypadku projektu wielomodułowego.

A_Di-Matteo
źródło
2
Zauważ, że MaxPermSize jest ignorowane, jeśli używasz JDK 8.
GeraldScott
14

Mam ten sam problem, próbując skompilować „czystą instalację” przy użyciu Lowend 512Mb RAM VPS i dobrego procesora. Uruchom OutOfMemory i wielokrotnie zabijaj skrypt.

Używałem export MAVEN_OPTS="-Xmx512m -XX:MaxPermSize=350m"i pracowałem.

Nadal pojawia się inny błąd kompilacji, ponieważ po raz pierwszy potrzebuję Mavena, ale problem OutOfMemory zniknął.

m3nda
źródło
11

Dodaj opcję

-XX:MaxPermSize=512m

do MAVEN_OPTS

maven-compiler-plugin opcje

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.5.1</version>
    <configuration>
      <fork>true</fork>
      <meminitial>1024m</meminitial>
      <maxmem>2024m</maxmem>
    </configuration>
  </plugin>
Ilya
źródło
2
Właściwie dodałem opcję -XX: MaxPermSize = 1024m, po utworzeniu tego postu. Ale nadal mam błąd braku pamięci. Inny post SO wspomniał, że muszę dodać opcję do argLine maven-surefire-plugin, aby podnieść pamięć używaną przez rozwidlone wątki. Zwiększyłem go do <argLine> -Xms256m -Xmx1024m -XX: PermSize = 128m -XX: MaxPermSize = 512m </argLine>
Kevin Meredith
Powinienem był o tym wspomnieć ... Nie, kompilacja mavenów wciąż się nie powiodła.
Kevin Meredith
Dodaj wszystkie te właściwości do maven-compilier-plugini zwiększ -XX:MaxPermSize, Xmxpowinno być =XX:MaxPermSize
Ilya
Użyj również opcji <fork> true </true> w maven-compilier-plugin
Ilya
Próbowałem tego (zobacz oryginalny post), ale moja kompilacja mvn nadal się nie udała.
Kevin Meredith,
4

Mam ten sam problem podczas kompilacji Druid.io, zwiększenie MaxDirectMemorySize w końcu zadziałało.

export MAVEN_OPTS="-Xms8g -Xmx8g -XX:MaxDirectMemorySize=4096m"
hahakubile
źródło
Ciekawe, że MaxDirectMemorySize jest pozornie nieograniczony domyślnie (tj. Dodałeś limit, a nie dostosowałeś wcześniej istniejącego).
Tomer Gabel
4

Poniższa konfiguracja działa w moim przypadku

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>${maven-surefire-plugin.version}</version>
    <configuration>
        <verbose>true</verbose>
        <fork>true</fork>
        <argLine>-XX:MaxPermSize=500M</argLine>
    </configuration>
</plugin>

Spróbuj użyć -XX: MaxPermSize zamiast -XX: MaxPermGen

Narayan Yerrabachu
źródło
4
_JAVA_OPTIONS="-Xmx3G" mvn clean install
Menadżer urządzeń
źródło
3

Na jakim systemie operacyjnym używasz?

Aby przypisać więcej niż 2 GB pamięci RAM, musi to być co najmniej 64-bitowy system operacyjny.

Jest też inny problem. Nawet jeśli Twój system operacyjny ma nieograniczoną pamięć RAM, ale jest ona podzielona w taki sposób, że nie jest dostępny ani jeden wolny blok 2 GB, wyjdziesz też z wyjątków pamięci. Pamiętaj, że normalna pamięć Heap jest tylko częścią pamięci używanej przez proces VM. Więc na 32-bitowej maszynie prawdopodobnie nigdy nie będziesz w stanie ustawić Xmx na 2048MB.

Sugerowałbym również ustawienie min maksymalnej pamięci na tę samą wartość, ponieważ w tym przypadku, gdy tylko maszyn wirtualnej zabraknie pamięci, pierwszy czas 1 GB zostanie przydzielony od początku, wówczas maszyna wirtualna przydziela nowy blok (zakładając, że zwiększa się on z 500 MB bloków) o wielkości 1,5 GB po przydzieleniu, skopiowałoby całą zawartość z pierwszego bloku do nowego i zwolniła pamięć. Jeśli ponownie zabraknie pamięci, 2 GB są przydzielane, a 1,5 GB jest następnie kopiowane, tymczasowo przydzielając 3,5 GB pamięci.

Christofer Dutz
źródło
1

Budując projekt na platformie Unix / Linux, ustaw składnię opcji Maven jak poniżej. Zwróć uwagę na pojedyncze znaki qoutation, a nie podwójne qoutation.

export MAVEN_OPTS='-Xmx512m -XX:MaxPermSize=128m'
ÖMER TAŞCI
źródło
0

Używanie .mvn / jvm.config działało dla mnie, a ponadto ma dodatkową zaletę w postaci połączenia z projektem.

colinbes
źródło
0

Dzieje się tak w dużych projektach w systemie Windows, gdy używany jest cygwin lub inny emulator systemu Linux (git bash). Przez przypadek oba nie działają w moim projekcie, który jest dużym projektem open source. W skrypcie sh jest wywoływanych kilka poleceń mvn. Rozmiar pamięci rośnie do rozmiaru stosu większego niż określony w Xmx i przez większość czasu w przypadku uruchamiania drugiego procesu systemu Windows. To sprawia, że ​​zużycie pamięci jest jeszcze większe.

Rozwiązaniem w tym przypadku jest użycie pliku wsadowego i zmniejszonego rozmiaru Xmx, a następnie operacje Maven zakończą się pomyślnie. Jeśli jest zainteresowanie, mogę ujawnić więcej szczegółów.

zhrist
źródło
0

Ktoś już wspomniał o problemie z 32-bitowym systemem operacyjnym. W moim przypadku problem polegał na tym, że kompilowałem z 32-bitowym JDK.

user2046211
źródło
0

Zwiększenie rozmiaru pamięci w zmiennej środowiskowej „MAVEN_OPTS” pomoże rozwiązać ten problem. U mnie zadziałało zwiększenie z -Xmx756M do -Xmx1024M.

Nidhi
źródło