Java Memory Leak bei RS232

Gast #2412072
Moin,

ich habe für ein Projekt Software-Teile dieser Website abgekupfert:
http://www.arduino.cc/playground/Interfacing/Java

Speziell geht es hier um den Abschnitt Sample Java Code und dann um
diesen Abschnitt:
1
/**
2
   * Handle an event on the serial port. Read the data and print it.
3
   */
4
  public synchronized void serialEvent(SerialPortEvent oEvent) {
5
    if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
6
      try {
7
        int available = input.available();
8
        byte chunk[] = new byte[available];
9
        input.read(chunk, 0, available);
10

11
        // Displayed results are codepage dependent
12
        System.out.print(new String(chunk));
13
      } catch (Exception e) {
14
        System.err.println(e.toString());
15
      }
16
    }
17
    // Ignore all the other eventTypes, but you should consider the other ones.
18
  }


Alles was über die RS232 rein kommt, wird ausgegeben. Aber es wird immer 
mehr Heap-Memory verbraucht. Auf dem PC läuft sonst nichts, außer eben 
mein Programm und Java VirtalVM.

Ich habe da die Zeilen
1
int available = input.available();
2
byte chunk[] = new byte[available];

in Verdacht. Kann ich das anders lösen?

Gruß
nochnCheffe
nochnCheffe schrieb:
> Kann ich das anders lösen?

Nicht wirklich. Java alloziert halt immer soviel speicher "wie geht", 
und versucht den Garbage Collector-Lauf, der den wieder freigeben würde, 
hinauszuzögern.
Wenn auf der Maschine sonst nix anderes läuft, wie du sagst, ist das 
auch die Richtige™ Strategie.

Wenn du lieber mehr freien + ungenutzen Ram hast: versuch die Garbage 
collection manuell anzustoßen: "System.gc()" oder so.

Oder konfigurier der VM weniger Speicher.
Persönliche Seite
Εrnst B✶ schrieb:
> versuch die Garbage
> collection manuell anzustoßen
Bitte nicht, das ist kontraproduktiv!

Εrnst B✶ schrieb:
> Oder konfigurier der VM weniger Speicher
Das schon eher...

nochnCheffe schrieb:
> Ich habe da die Zeilen in verdacht
Die beiden Zeilen sind korrekt, dafür ist das lesen und die AUsgabe 
nicht 100% koscher, führen aber zu keinem Memmory leak.
Man könnte sich ja auch den chunk als Member in der Klasse halten und 
nur dann einen neuen anfordern, wenn eine größere Speicherfläche 
benötigt wird. Dann wird am Anfang der Speicherverbrauch etwas steigen, 
bis sich dann das System auf die maximal vorkommende Größe eingependelt 
hat und ab dort konstant bleiben.
Persönliche Seite
nochnCheffe schrieb:
> Moin, wie macht man es besser?

Read hat einen Rückgabewert welchen man auswerten sollte, außerdem 
sollte man bei der Umwandlung byte zu char immer das Charset angeben:
1
int read = input.read(chunk, 0, available);
2
if (read > 0) {
3
  System.out.print(new String(chunk, 0, read, "UTF-8"));
4
}

Karl Heinz Buchegger schrieb:
> Man könnte sich ja auch den chunk als Member in der Klasse halten
Wenn es sich um einen einbyte Zeichensatz hadelt ginge auch:
1
while(input.available() > 0) {
2
  System.out.println((char)input.read());
3
}

Für Multibyte ist das Beispiel aber eh nicht ausgerüstet... Falls du 
wirklich Zeichen lesen willst wäre ein Reader mit einem 
BufferedInputStream welcher in einem eigenem Thread ausgeführt wird eh 
besser geeigent, in den Meisten Fällen will man eh Zeilenweise lesen, da 
ist der Eventbasierte Ansatz eh nicht so pralle...
1
    BufferedReader reader = new BufferedReader(new InputStreamReader(new BufferedInputStream(input, 100)));
2
    String line;
3
    while ((line = reader.readLine()) != null) {
4
      System.out.println(line);
5
    }

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.