2015-02-22 7 views
8

Mam aplikację Java opracowaną w Eclipse Luna w Windows, która działa w Amazon EC2 (c3.large, Amazon Linux). Ta aplikacja przetwarza pracę z bardzo stałą stawką przychodzącą. Kiedy buduję aplikację na JDK 8u31, obciążenie procesora EC2 jest znacznie wyższe niż ta sama aplikacja zbudowana przeciwko JDK 7u75.Procesor aplikacji Java/obciążenie znacznie wyższe w porównaniu do JDK8

Aplikacja pierwotnie działała z domyślnym środowiskiem JRE w EC2, a ja dodałem OpenJDK 1.8.0.31, aby móc skorzystać z funkcji waitFor Java 8 Process (long timeout, jednostka TimeUnit). Głównym zadaniem tej aplikacji jest wywoływanie aplikacji za pomocą Runtime.exec.

$ sudo alternatives --config java 

There are 2 programs which provide 'java'. 

    Selection Command 
----------------------------------------------- 
* 1   /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/java 
+ 2   /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.31-2.b13.5.amzn1.x86_64/jre/bin/java 

średnie obciążenie przykład, gdy aplikacja jest zbudowany na 1,7:

top - 00:20:28 up 4 days, 10:41, 4 users, load average: 0.37, 0.26, 0.52 

średnie obciążenie przykład, gdy aplikacja jest zbudowany na 1,8:

top - 23:45:52 up 4 days, 10:06, 4 users, load average: 2.28, 2.60, 2.01 

Wydaje się, że może to być związane do Open JDK 1.8.0.31, ale nie wiem jak to debugować. Nie ma zmian w kodzie, zmieniam tylko poziom zgodności i buduję od 1.7 do 1.8 w Eclipse Luna. Jakiś pomysł, dlaczego ładunek byłby tak inny?

UPDATE:

widzę podobny ładunek wysokiej CPU podczas korzystania z Oracle JDK na EC2.

$ sudo alternatives --config java 

There are 3 programs which provide 'java'. 

    Selection Command 
----------------------------------------------- 
    1   /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/java 
    2   /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.31-2.b13.5.amzn1.x86_64/jre/bin/java 
*+ 3   /usr/java/jdk1.8.0_31/bin/java 

obciążenia średnia:

top - 01:45:27 up 4 days, 12:06, 4 users, load average: 2.28, 1.50, 1.04 
+0

Czy możesz odtworzyć to na własnej maszynie? – fge

+0

Widziałem go na wielu instancjach EC2 (zarówno OpenJDK). Nie mogę wygenerować obciążenia na mojej lokalnej maszynie, ale przyjrzę się sposobom symulacji pracy. – DanielB6

+0

Aby rozróżnić efekty kompilatora vs.jre: co się stanie, jeśli skompilujesz na zgodność 1.7 i uruchomisz 1.8 jre? –

Odpowiedz

1

Dokumentacja mówi: „Domyślna implementacja tej metody sondaży exitValue aby sprawdzić, czy proces ten został zakończony Konkretne implementacje tej klasy są zachęcani, aby zastąpić to. metoda z bardziej wydajną implementacją. "

Podejrzewam, że to jest powód.

Zobacz http://docs.oracle.com/javase/8/docs/api/java/lang/Process.html#waitFor--

+0

Myślę, że jest to możliwe w przypadku, gdy proces.waitFor (30, TimeUnit.SECONDS) jest używany. Nie wyjaśnia to przypadku, w którym nie ma zmiany kodu, ten sam process.waitFor() jest używany w wersjach 1.7 i 1.8. – DanielB6

+1

Zgadza się, przegapiłem to w komentarzu. Może implementacja waitFor() jest wadliwa w wersji 1.8 i wywołuje wersję z limitem czasu? To brzmi jak przypadek męczącej redukcji do minimalnego przykładu ... –

3

pan opisane objawy, ale nie sądzę, że to wystarczy, aby przejść dalej, choćby dlatego, że będzie to niemożliwe, aby szukać rzeczy jak „Java 8 wysokiej CPU” Anywhere (Google , parada błędów Java itp.) i znaleźć użyteczne wyniki. Niestety, musisz zebrać więcej informacji o tym, co używa procesora. Oto kilka pomysłów, jak to zrobić:

  1. Profil z narzędziem takim jak VisualVM. Różnice w obciążeniu są ekstremalne, więc możesz po prostu dostrzec, co używa procesora.
  2. Znajdź zajęte wątki. Możesz wziąć kilka migawek nitki i oczyścić go, lub wypróbować narzędzie takie jak jvmtop.
  3. Sprawdź, co robi śmieciarz, włączając włączanie rejestrowania GC lub za pomocą narzędzia takiego jak jstat.
  4. Użyj strace do śledzenia wykonywania wywołań systemowych.
+0

Dzięki za te informacje, popatrzę na te narzędzia i odeślę wyniki, które zbieram. – DanielB6