2017-01-25 2 views
1

Wir haben eine Java-Anwendung als lange laufenden Dienst haben (tatsächliche up-Zeit für diese JVM 31 Tage 3 Stunden 35 min)JVM undichter Speicher außerhalb Heap und Pufferpools

Durch Windows-Taskmanager des Prozesses verwendet 1075384320 B - fast ein GB. kein Leck hier

Buffer Pools -

Heap Größe der JVM auf 256 MB (-Xmx256m)

Speicher-Daten

Memory: 
Size: 268,435,456 B 
Max: 268,435,456 B 
Used: 100,000,000 up to 200,000,000 B 

eingeschränkt

Direct: 
Count: 137 
Memory Used and Total Capacity: 1,348,354 B 

Mapped: 
Count: 0 
Memory Used and Total Capacity: 0 B 

- kein Leck hier

meine Frage: wo sich die JVM den zusätzlichen Speicher verwendet?

Zusätzliche Informationen:

Java: version 1.8.0_74 32 bit (Oracle) 

Classes: 
Total loaded: 17,248 
Total unloaded: 35,761 

Threads: 
Live: 273 
Live peak: 285 
Daemon: 79 
Total started: 486,282 

Nach einem Neustart es einige Tage für die Prozessgröße nimmt zu wachsen, so natürlich regelmäßigen Neustart helfen würde, und vielleicht eine neuere Java-Version verwenden auch das Problem lösen kann , aber ich hätte gerne eine Erklärung für dieses Verhalten, e. G. bekannter Bug in 1.8.0 vor 111, behoben in ... - Ich habe noch nichts gefunden.

Wir verwenden etwa 350 solcher Installationen an verschiedenen Orten, so dass der Wechsel nicht so einfach ist.

+0

Werfen Sie einen Blick auf den verwendeten Speicher mit jvisualvm. Sie finden es in JDK_HOME/bin. Sie können dann die lebenden Instanzen Ihrer Klassen zählen. –

+0

Was denkst du, wo ich die obigen Daten verfolge? –

+0

Wie Sie oben sehen, sind geladene Klassen 17.248; Metaspace verbraucht ungefähr 58 M. –

Antwort

0

Vergessen Sie nicht, Ihre JVM im Servermodus für lange laufende Aufgaben auszuführen!

Der Grund für diese Art von Speicherverlust war, dass die JVM im Clientmodus ausgeführt wurde. Unsere Lösungen laufen in einigen Filialen auf alten Windows XP 32-Bit-PCs. Der Standardwert für JVMs auf dieser Plattform ist der Client-Modus.

In den meisten Fällen wird JRE 1.8.0_74-32bit ausgeführt. Mit unserer Anwendung verliert diese JVM Speicher in "Thread Arena Space" - scheint nichts zurückgegeben zu werden.

Nach dem Wechsel in den Server-Modus durch Setzen des Parameters -server auf JVM starten die Probleme verschwunden.

0

Es gibt zwei Gründe für die Off-Heap-Speicherverbrauch:

  • Ihre Anwendung oder eine der Bibliotheken Sie verwenden (zB JDBC-Treiber) ausführen etwas nativ (ein Modul über JNI aufgerufen)
  • Ihre Anwendung oder eine der Bibliotheken verwendet den Off-Heap-Speicher auf andere Weise, dh mit direkten Puffern oder mit einer "cleveren" Verwendung von sun.misc.Unsafe.

können Sie überprüfen dies die native Speichernutzung mit jcmdas explained here Tracking (Sie müssen die Anwendung neu starten).

+1

Gepufferte Pools (direkt oder verwaltet) können von JVisualvm oder JConsole (MBeans) überwacht werden - sehr geringer Speicherverbrauch. Der 'committed virtual memory' in JConsole und die Größe im Taskmanager stimmen überein, so dass die JVM den Speicher, den sie verbraucht," kennt ". Ich habe einige der Installationen mit aktivierter "nativer Speicherverfolgung" gestartet und ich hoffe, den Speicherbereich auf diese Weise zu finden. –

+0

Während ich darauf wartete, dass meine neu gestarteten Prozesse groß wurden, analysierte ich einen weiteren bereits großen Prozess mit VMMap von Sysinternals. Es gibt große Blöcke (mehrere 300 MB) von "privaten Daten" zwischen DLLs. Morgen werde ich ein wenig nach Erklärungen suchen. –

+0

Leider ist mir die Speicherverwaltung auf der Windows-Plattform nicht mehr vertraut ... –

Verwandte Themen