Java Memory Leak bei RS232

Gast #2412072
Lesenswert?

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
#2412117
Lesenswert?

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 #2412234
Lesenswert?

Ε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.
#2412270
Lesenswert?

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 #2412440
Lesenswert?

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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren