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>

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 ...


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.


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ął.


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>

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"

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



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.


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'

0

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


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.


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.


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.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.