2016-12-28 10 views
7

Używamy SBT 0.13 i JVM Java 8 na CircleCI, aby zbudować aplikację Play z kilkoma podprojektami. Czasami wychodziliśmy z problemów z pamięcią w CircleCI, gdzie przerwano naszą kompilację, ponieważ przekraczało to 4 GB pamięci.SBT brak pamięci z podprojektami

Wczoraj dodałem nowy podprojekt do naszej kompilacji, a prawie wszystkie kompilacje zawiodły teraz w przypadku braku pamięci. Wygląda na to, że dodanie podprojektów również zwiększa ilość pamięci używanej w naszej kompilacji.

Próbowałem kilka rzeczy, aby zmniejszyć obciążenie pamięci:

  • Dodaj _JAVA_OPTIONS: "-Xms512m -Xmx2048" do circle.yml jak opisano na CircleCI's documentation pages. (Zauważyłem z rejestru, że maszyna JVM odbiera to ustawienie.)
  • Dodaj parametr -mem do wywołania SBT.
  • Dodaj concurrentRestrictions in Global += Tags.limit(Tags.Test, 1) na górze pliku SBT, aby upewnić się, że przynajmniej pamięć nie jest używana jednocześnie.

Wydaje się, że wszystkie te środki pomogły, ale nie znalazłem jeszcze ostatecznego rozwiązania tego problemu.

Co jeszcze mogę zrobić, aby utrzymać wykorzystanie pamięci SBT pod kontrolą?

EDIT: Nasz projekt ma 5 podprojektów, z około 14.000 linii kodu Scala (a także, 21000 linii kodu Java, które dziedziczone). Brak pamięci zwykle (ale nie zawsze) występuje podczas wykonywania analizy statycznej za pomocą FindBugs: używamy tego w połączeniu z pluginem FindSecurityBugs, aby znaleźć problemy bezpieczeństwa.

+0

jaki jest twój projekt? ile linii kodu masz?kiedy dostaniesz OOM podczas kompilacji? opakowanie? faza testów? – Rumoku

+0

@rumoku Dobre pytania; Zmieniłem moje pytanie, by na nie odpowiedzieć. – jqno

+0

Widzisz problemy w innej fazie niż w tym drugim pytaniu, ale może ci to pomóc: http://stackoverflow.com/questions/16640823/sbt-runs-out-of-memory?rq=1 – 2rs2ts

Odpowiedz

1

tam dwa problemy tutaj, że są coraz mieszany:

  1. Koło CI nie podniesienie wartości limitów pamięci

  2. SBT użyciem nadmiernej ilości pamięci

Pierwszy problem należy rozwiązać, patrząc na dokumentację/przykłady CircleCI. Aby zbadać, dlaczego korzystasz z tak dużej ilości pamięci, możesz uruchomić lokalnie sbt z limitami pamięci niższymi niż 4g (czyli 2g). Znajdziesz się w jednym z tych dwóch przypadków:

  1. Twoje testy naprawdę zużywają zbyt dużo pamięci, może z powodu przecieków pamięci. Twoja maszyna wirtualna JVM wychodzi z powodu java.lang.OutOfMemoryError: GC overhead limit exceeded. Powinieneś uruchomić kompilację lokalnie z profilerem i zobaczyć, co jest przyczyną problemu (połączenia z bazą danych nie są zamknięte?)

  2. Twoje testy zużywają zbyt dużo pamięci dzięki możliwości dynamicznego ładowania klas SBT: w SBT jest to możliwe ponownie załadować klasę całkowicie w tej samej maszynie JVM (np. można uruchomić konsolę, załadować klasę, edytować plik, ponownie skompilować i ponownie uruchomić konsolę i ponownie załadować klasę). Jak opisano w dokumentacji Oracle tutaj, nie ma ograniczeń dla Maximum MetaSpace w Javie 8 i powinieneś ustawić jedną tak, aby twoja sterty + metaspace < 4gb. Zobacz https://blogs.oracle.com/poonam/entry/about_g1_garbage_collector_permanent

+0

1. Zrobiłem również wszystkie rzeczy wymienione w pytaniu na miejscu. Ograniczałem wszystko do 1,5G, ale za każdym razem widzę, że pamięć sięga aż 2,5G. Zrobiłem profilowanie biedaka za pomocą 'top' w terminalu, chociaż wiem, że nie jest to właściwy sposób. 2. Nie wiedziałem o tej metaprzestrzeni. Na pewno spróbuję tego! Chociaż po prostu uruchamiam 'test sbt' i zostawiam pliki sam podczas działania. – jqno

+0

Zawód JVM to nie tylko sterty, ale zawiera również MetaSpace. Czy twoje testy się powiodły, ograniczając pamięć do 2g sterty? – Edmondo1984

+0

Nie próbowałem jawnie ustawiać metaprzestrzeni (chociaż z tego co rozumiem, przełącznik '-mem 'SBT powinien to zrobić). Postaram się ustawić "-XX: MetaspaceSize" później i złożyć raport. – jqno