2015-02-22 3 views
8

Ich habe eine Java-Anwendung in Eclipse Luna in Windows entwickelt, die in Amazon EC2 (c3.large, Amazon Linux) läuft. Diese Anwendungsprozesse arbeiten mit einer sehr konstanten Eingangsrate. Wenn ich die Anwendung gegen JDK 8u31 erstelle, ist die EC2-CPU-Last viel höher als die gleiche Anwendung, die gegen JDK 7u75 gebaut wird.Java-Anwendung CPU/laden viel höher, wenn gegen JDK8 gebaut

Die Anwendung lief ursprünglich mit der Standard-JRE auf EC2, und ich habe die OpenJDK 1.8.0.31 hinzugefügt, um die Vorteile von Java 8 Process waitFor (langes Timeout, TimeUnit-Einheit) zu nutzen. Die Hauptaufgabe dieser Anwendung besteht darin, eine Anwendung mit Runtime.exec aufzurufen.

$ 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 

Beispiel durchschnittliche Belastung, wenn die Anwendung gegen 1,7 gebaut:

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

Beispiel durchschnittliche Belastung, wenn die Anwendung gegenüber 1,8 gebaut:

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

Es scheint, wie es in Zusammenhang stehen kann zum Open JDK 1.8.0.31, aber ich weiß nicht, wie ich das debuggen kann. Es gibt keine Codeänderungen, ich ändere lediglich die Compliance-Stufe und baue zwischen 1,7 und 1,8 in Eclipse Luna. Irgendeine Idee warum die Ladung so viel anders wäre?

UPDATE:

ich ähnlich hohe CPU-Last zu sehen, wenn ich die Oracle JDK auf EC2 verwenden.

$ 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 

Last Durchschnitt:

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

Können Sie dies auf Ihrer eigenen Maschine reproduzieren? – fge

+0

Ich habe es auf mehreren EC2-Instanzen (beide OpenJDK) gesehen. Ich kann die Arbeitslast auf meinem lokalen Computer nicht generieren, aber ich werde nach Möglichkeiten suchen, die Arbeit zu simulieren. – DanielB6

+0

Um Effekte von Compiler vs zu unterscheidenjre: Was passiert, wenn Sie bei compliance 1.7 kompilieren und auf dem 1.8 jre laufen? –

Antwort

1

Die Dokumentation sagt: „Die Standardimplementierung dieser Methoden fragt die exitValue zu überprüfen, ob der Prozess beendet hat konkrete Implementierungen dieser Klasse sind stark diese außer Kraft zu setzen gefördert. Methode mit einer effizienteren Implementierung. "

Ich vermute stark, dass dies der Grund ist.

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

+0

Ich denke, das ist für den Fall möglich, in dem process.waitFor (30, TimeUnit.SECONDS) verwendet wird. Es wird nicht der Fall erläutert, in dem keine Codeänderung stattfindet, der gleiche Prozess. WaitFor() wird in 1.7 und 1.8 verwendet. – DanielB6

+1

Das stimmt, das habe ich im Kommentar verpasst. Vielleicht ist die waitFor() - Implementierung in 1.8 fehlerhaft und ruft die Version mit Timeout auf? Das klingt wie ein Fall für eine langwierige Reduktion auf ein minimales Beispiel ... –

3

Sie Symptome beschrieben habe, aber ich glaube nicht, das genug ist, um zu gehen, wenn auch nur, weil es unmöglich sein wird, für Dinge wie „Java 8 hohe CPU“ überall suchen (Google , die Java Bugparade, etc.) und nützliche Ergebnisse finden. Leider müssen Sie mehr Informationen darüber sammeln, was mit der CPU arbeitet. Hier sind einige Gedanken dazu:

  1. Profil mit einem Tool wie VisualVM. Die Lastunterschiede sind extrem, so dass Sie möglicherweise nur feststellen können, was mit der CPU arbeitet.
  2. Finden Sie die beschäftigten Themen. Sie können eine Reihe von Thread-Snapshots und Augapfel nehmen, oder versuchen Sie ein Werkzeug wie jvmtop.
  3. Überprüfen Sie, was der Garbage Collector gerade macht, indem Sie die GC-Protokollierung aktivieren oder ein Tool wie jstat verwenden.
  4. Verwenden Sie strace, um die Ausführung von Systemaufrufen zu verfolgen.
+0

Danke für diese Informationen, ich werde mir diese Tools anschauen und alle Ergebnisse, die ich sammle, zurücksenden. – DanielB6

Verwandte Themen