2016-03-23 6 views
10

Wir haben einen Java-Prozess unter Solaris 10, der etwa 200-300 gleichzeitige Benutzer bedient. Die Administratoren haben berichtet, dass der vom Prozess verwendete Speicher im Laufe der Zeit erheblich zunimmt. Es erreicht 2GB in wenigen Tagen und hört nie auf zu wachsen.Java-Prozessspeicher wächst unbegrenzt. Speicherleck?

Wir haben den Heap freigegeben und mit Eclipse Memory Profiler analysiert, konnten aber dort nichts Außergewöhnliches erkennen. Die Heap-Größe war sehr klein.

Nach dem Hinzufügen der Speicherstatusprotokollierung zu unserer Anwendung haben wir eine Diskrepanz zwischen der Speicherauslastung des vom Administrator verwendeten "top" -Dienstprogramms und der von MemoryMXBean und Runtime-Bibliotheken gemeldeten Verwendung gefunden.

Hier ist eine Ausgabe von beiden.

Memory usage information 

From the Runtime library 
Free memory: 381MB 
Allocated memory: 74MB 
Max memory: 456MB 
Total free memory: 381MB 

From the MemoryMXBean library. 
Heap Committed: 136MB 
Heap Init: 64MB 
Heap Used: 74MB 
Heap Max: 456MB 
Non Heap Committed: 73MB 
Non Heap Init: 4MB 
Non Heap Used: 72MB 

Current idle threads: 4 
Current total threads: 13 
Current busy threads: 9 
Current queue size: 0 
Max threads: 200 
Min threads: 8 
Idle Timeout: 60000 

    PID USERNAME NLWP PRI NICE SIZE RES STATE TIME CPU COMMAND 
99802 axuser 115 59 0 2037M 1471M sleep 503:46 0.14% java 

Wie kann das sein? top-Befehl meldet so viel mehr Verwendung. Ich hatte erwartet, dass RES in der Nähe von Heap + Non-Heap sein sollte.

pmap -x jedoch berichtet, die meisten der Speicher im Heap:

Address  Kbytes  RSS  Anon  Locked Mode Mapped File 
*102000   56   56   56  - rwx---- [ heap ] 
*110000  3008  3008  2752  - rwx---- [ heap ] 
*400000 1622016 1621056 1167568  - rwx---- [ heap ] 
*000000  45056  45056  45056  - rw----- [ anon ] 

Kann jemand bitte etwas Licht auf diesem verschütten? Ich bin völlig verloren.

Danke.

aktualisieren

Dies scheint nicht ein Problem unter Linux zu sein.

Basierend auf der Antwort von Peter Lawrey ist der von pmap gemeldete "Heap" nativer Heap, nicht Java Heap.

+5

Gibt es native Bibliotheken in dieser Anwendung? – JimmyJames

+6

Der von pmap gemeldete "Heap" ist wahrscheinlich der native Heap, nicht der Java-Heap. Welche Ressourcen könnte die Anwendung im nativen Bereich verwenden? –

+0

Ehrlich gesagt bin ich mir nicht sicher. Wir haben Jetty-Server in unserer Anwendung, die REST-Aufrufe verarbeitet. Abhängig von dem Aufruf können wir select/insert/delete gegen die Datenbank mit ojdbc ausführen oder einige I/O durchführen. Also meine Vermutung ist, ja, wir verwenden die nativen Bibliotheken, aber ich bin nicht sicher, was sie sind? Gibt es eine Liste von nativen Java-Bibliotheken, auf die ich verweisen kann? –

Antwort

1

In Garbage-Collected-Umgebungen bedeutet das Festhalten an unbenutzten Zeigern das "Ausbleiben von Leak" und verhindert, dass der GC seine Aufgabe erfüllt. Es ist wirklich einfach versehentlich Zeiger zu halten.

Ein häufiger Schuldiger ist Hashtables. Ein weiterer Punkt sind Arrays oder Vektoren, die logisch gelöscht werden (indem der Wiederverwendungsindex auf 0 gesetzt wird), aber wo der tatsächliche Inhalt des Arrays (über dem Verwendungsindex) immer noch auf etwas zeigt.

+0

Wäre nicht das, was Sie beschreiben, ein Leck auf dem Haufen? –

+3

Die ursprüngliche Frage erwähnt, dass die Heap-Größe (etwas) stabil ist; Es ist die "native" Speichergröße, die zunimmt. Dies deutet auf ein Leck hin, das nicht auf Java-Objekte bezogen ist. Hashtables sind * nicht * das Problem, hier, oder sie würden in einem Heap-Dump erscheinen, der viele lebende Java-Objekte zeigt. –

+0

Guter Punkt. Leck undichte Ressourcen sind eher ein Täter. Dinge wie Dateien geöffnet, aber nicht geschlossen. Threads gestartet, aber nicht beendet. Einige Speichertypen, z. B. Klassen, sind überhaupt nicht erfassbar. – ddyer