2014-09-14 8 views
11

Ich habe ein System in Scala, mit vielen simultanen Threads und Systemaufrufen. Dieses System hat ein Problem, da die Speicherbelegung im Laufe der Zeit zunimmt.Speicherleck in Scala und Prozesse

Das folgende Bild zeigt die Speichernutzung für einen Tag. Wenn es ans Limit kommt, schaltet sich der Prozess ab und ich setze einen Wachhund, um ihn wieder zu finden. inserir a descrição da imagem aqui

Ich betreibe regelmäßig den Befehl

jcmd <pid> GC.run 

Und das macht die Erinnerung langsam zu erhöhen, aber das Leck immer noch geschieht.

Ich analysierte mit jvisualvm, im Vergleich zu bestimmten Zeitpunkten, mit 40 Minuten Delta. Das Bild unten zeigt den Vergleich zwischen diesen beiden Zeitpunkten. Beachten Sie, dass es für Instanzen einiger Klassen wie ConcurrentHashMap$HashEntry, SNode, WeakReference, char[] und String und viele Klassen im Paket scala.collection.concurrent eine Erhöhung gibt.

memory leaked ojects

Was den Speicherverlust verursacht werden kann?

Edit 1: jvisualvm Untersuchung, bemerkte ich, Objekt von CNode und INode Klassen, die in TriedMap sind, dass innerhalb sbt.TrapExit $ App Klasse instanziert wird. Hier ist die Objekthierarchie Figur:

object hierarchy

+1

http://stackoverflow.com/questions/1218872/avoiding-scala-memory-leaks-scala-constructors?rq=1 http://stackoverflow.com/questions/7944148/weakreference-and-memory-leaks http : //stackoverflow.com/questions/3871960/long-lived-java-weakreferences – Tony

+0

Ich sehe list.toStream.map, aber woher kommen die scala.collection.concurrent? Wenn Sie "viele Threads" sagen, meinen Sie "foo.par" viel? Ich frage nicht als Experte in parallelen Sammlungen. Verwenden Sie explizit eine TrieMap? –

+0

Viele Threads Ich meine, es gibt Hunderte von Akteuren, jeder Akteur führt Systemaufrufe durch und erstellt einige Futures, um Aufgaben asynchron auszuführen. Ich verwende TrieMap nicht explizit. –

Antwort

1

Erste capture eine Heapdump, wenn die Anwendung abstürzt aufgrund einer aus Speicherproblem. Fügen Sie die folgenden Flags, wenn die JVM beginnend

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/to/dump 

Als nächstes müssen Sie die Heapdump analysieren, um die Quelle des Speicherleck, um herauszufinden. Ich empfehle die Verwendung Eclipse MAT. Der Leak Suspects Bericht sollte Ihnen ein Gefühl dafür geben, welche Objekte das Leck tatsächlich verursachen.

+0

Mit den Heap-Diffs habe ich schon die Idee, was die Quelle des Lecks ist. ConcurrentHashMap $ HashEntry sind steigende Zahlen. Aber ich benutze diese Objekte nicht in meinem Code, so dass es aussieht wie etwas in der Scala oder jvm –

+0

Sie können nicht direkt die Objekte instanziieren, aber es passiert. Sie müssen also zurückverfolgen, was/wann/wo diese Objekte erstellt werden. Also, wer die CNode-Instanz usw. anlegt. Einige Objekte behalten einen Verweis auf den CNode, der verhindert, dass sie (und die Objekte, auf die sie verweist) von der Garbage Collection erfasst werden. Eclipse MAT hat diese Ansicht - http://help.eclipse.org/luna/index.jsp?topic=%2Forg.eclipse.mat.ui.help%2Ftasks%2Ffindingresponsibleobjects.html, die Ihnen einige Informationen geben sollte. – rrevo

0

Ohne die Implementierung zu sehen ist schwer zu sagen. Der Titel Ihres Posts deutet darauf hin, dass es in Scala ein Speicherleck gibt, aber haben Sie Ihre Implementierung auf Probleme mit der Freigabe von Objekten überprüft?

Haben Sie überprüfen folgendes:

  • Beschränken Sie Zahl der an allen Akteuren?
  • Legen Sie Timeouts für Systemaufrufe fest?
  • Erlauben Sie den Schauspielern, von Heap entfernt zu werden, wenn sie ihre Aufgaben ausführen?
  • Haben Sie zählen, wie viele Akteure in den Speicher aufgenommen werden kann oder Sie erstellen nur „Hunderte von Schauspielern“ mit der Hoffnung, dass Jvm wissen „was zu tun ist“

Was ich versuche zu sagen, dass vielleicht hast du keinen Speicher mehr, weil du einfach zu viele Objekte erstellst, die später nicht mehr freigegeben werden, weil sie entweder ihre Aufgaben noch ausführen (kein Timeout) oder du zu viele erstellt hast.

Vielleicht müssen Sie Ihre Anwendung auf viele jvms skalieren? Wie viele jvms verwendest du?