2015-11-02 6 views
6

Ich hatte einen Anruf eines Kunden am letzten Wochenende erzählte mir, dass ihr Java-Programm nicht reagierte, wenn Sie einen Import von Daten. Die Daten sind eine einfache Excel-Arbeitsmappe mit 4 Arbeitsblättern. Alle Daten werden aus den Spalten gelesen und einer Datenbank hinzugefügt.Battling Java-Heap-Größe, großer Unterschied zwischen Java lokal und Java Web Start

Also begann ich zu untersuchen und hatte einige seltsame Ergebnisse.

  1. Testen des Imports mit Run in Netbeans. Dies nutzt Java 64-Bit-Instanz:

Erster Lauf

local first run (64-bit)

zweiten Lauf

local second run (64-bit)

  1. Testen der Import mit Java Web Start. Dies wird durch das Öffnen einer JNLP-Datei gestartet wird, und verwendet eine Java-32-Bit-Instanz:

Erster Lauf

webstart first run (32-bit)

In diesem Fall hatte ich das gleiche Problem, das der Kunde war Berichterstattung, das Programm reagiert nicht mehr, nachdem es den Importprozess durchlaufen hat. Dies liegt daran, dass ich die maximale Heap-Größe erreiche, soweit ich das beurteilen kann (roter Kreis).

zweiter Lauf

Also habe ich beschlossen habe, indem es die folgend meine JNLP-Datei die anfängliche Heap-Größe und max Heap-Größe zu erhöhen: initial-heap-size="512m" max-heap-size="1024m". Als ich den Import erneut getestet, es schien zu arbeiten, aber ich merke es früher viel mehr Speicher in den ersten 2 Fälle verglichen wird:

webstart second run (32-bit)

  • Warum gibt es einen 300mb Unterschied in der Speichernutzung zwischen Fall 1 und 2 im Vergleich zu Fall 4?
  • Ist diese hohe Speichernutzung das Ergebnis schlechter Programmierung oder eines Speicherlecks? Oder ist es normal so hohe Werte zu haben?
  • Fügt initial-heap-size="512m" max-heap-size="1024m" eine gültige Lösung für dieses Problem hinzu?
+4

@StackFlowed Ich bezweifle das sehr. – Kayaman

Antwort

2

Nun, die offensichtlichen Unterschiede sind, dass Ihre erste Läufe mit einem 64-bit server VM fertig sind und die letzteren sind mit einem 32-bit client VM getan.

Angeblich ist die Client-VM für eine bessere Benutzerfreundlichkeit in einer Desktop-Anwendung optimiert, und die Server-VM ist für "Server" -Arbeit optimiert. Ich habe keine vollständige Liste der Unterschiede (oder ob es wirklich etwas ist, das in tatsächlichen Anwendungsfällen gut funktioniert). Zitieren Sie mich nicht dazu, aber ich glaube, dass die Client-VM GC mehr als die Server-VM vermeidet, weil sie zumindest an einem Punkt als langsam empfunden wurde.Das würde erklären, warum die Client-VM viel mehr Speicher verwendet, anstatt sie aggressiv freizugeben.

Das Gerede mit den GC-Parametern ist manchmal die richtige Sache, und in diesem Fall ist es das einzige, was Sie tun können, es sei denn, Sie identifizieren signifikante Speicherlecks. Es ist keine schlechte Idee, sich darüber im Klaren zu sein, was den GC in jedem Fall antreibt.

+0

Vielen Dank für Ihre Antwort, ich habe meine Anwendung weiter auf Speicherlecks überprüft, indem ich Eden & Old Gen Space angeschaut habe, aber nichts Spektakuläres gesehen habe. Für jetzt ist es mit der anfänglichen Heap-Größe und Max-Heap-Größe behoben, aber ich werde sehen, ob ich meinen Code mehr optimieren kann. Ich denke, die Speicherspitzen werden durch das Ein-/Ausblenden von Steuerelementen verursacht. Obwohl ich denke, sollte es die Referenzen behalten, anstatt neue in Erinnerung zu schaffen? – Perneel

+0

Ja, wenn Sie nur eine Komponente ausblenden, ist sie nicht für GC geeignet. Sie sollten den Speicher-Sampler eine Weile ausführen, um festzustellen, ob Sie andere Hotspots identifizieren können. – Kayaman

+1

Ich habe meinen Code geändert. Ich habe viele Datenbankanforderungen zum Erstellen von Entitäten basierend auf Benutzereingaben gestellt, wobei immer ein Client-Objekt erstellt wurde, um diese Anfrage zu bearbeiten. Scheint, dass dies die Speicherprobleme verursacht hat. Ich lege nun alle zu erstellenden Entitäten in einen Wrapper und erstelle sie in einer einzigen Anfrage. – Perneel

Verwandte Themen