1

My app connects to a Wi-Fi peripheral. I’m using Socket.getInputStream() and Socket.getOutputStream() to read/write data. When the connection is established I store these two streams so that I can reuse them as long as I’m connected. My app sends a command via the OutputStream every second and reads the result from the InputStream by its read() method. After some time I get an "OutOfMemoryError". Correct me if I’m wrong but I think this is because read() does not remove the read data from the InputStream, right?

My question is: Is it a good practice to store the Streams? Or should I use Socket.getInputStream(), Socket.getOutputStream() every time I send a new command?

It seems not to be a problem with the OutputStream since I can call flush() for that. What about reset() of InputStream? Does this remove the data for the stream?

Here is the code how I encapsulate my Streams:

@Override
public InputStream getInputStream() throws IOException {
    return _Socket.getInputStream();
}

@Override
public OutputStream getOutputStream() throws IOException {
    return _Socket.getOutputStream();
}

@Override
public void connect() throws IOException {
    try {
        SocketAddress socketAddress = new InetSocketAddress(_ip, _port);

        _Socket = new Socket(_ip, _port);
    } catch (IOException e) {
        MyExceptionHandler.appendLog(MyExceptionHandler.exceptionToString(e));

        throw e;
    }
}

The code for sending and receiving commands comes from this api:

https://github.com/pires/obd-java-api/blob/master/src/main/java/com/github/pires/obd/commands/ObdCommand.java

The exception does also not come immediately. It occurs after ~30 Minutes and a lot of commands sent/received

6
  • 1
    You should definitely show some code. Commented Aug 15, 2015 at 21:06
  • 1
    Streams from a regular java.net.Socket definitely do not store any of the data. Your problem is somewhere else. Commented Aug 15, 2015 at 21:09
  • 2
    The condition of your while is dodgy. If you reach the end of the stream before encountering a \n, -1 is returned indefinitely and you have an infinite loop. If you allocate memory in the body of the loop (possibly in your StringBuilder adding -1 over and over again) you will eventually run out of memory. It's only speculation because you're not showing the body of the loop. Commented Aug 15, 2015 at 21:21
  • Why don't you just try what you're suggesting yourself "Or should I use “Socket.getInputStream(), Socket.getOutputStream() every time I send a new command?" and see if it fixes your problem? My guess is it won't, but at least if you try it you can let go of the idea that there is an issue with the streams. Commented Aug 15, 2015 at 21:28
  • It is already late and I don't have any devices right now Commented Aug 15, 2015 at 21:29

1 Answer 1

3

Correct me if I’m wrong but I think this is because “read()” does not remove the read data from the InputStream, right?

Wrong. If you're running out of memory it's not because of InputStream. You have a bug in your code.

My question is: Is it a good practice to store the Streams?

Yes.

Or should I use “Socket.getInputStream(), Socket.getOutputStream() every time I send a new command?

No.

What about “reset()” of InputStream? Removes this the data for the stream?

No, it does what it says in the Javadoc.

EDIT The code you have linked to is at first inspection a load of rubbish. It never checks for end of stream for example, so when that happens it will read forever, accumulating 0xff bytes and eventually filling up memory. Find something better.

Sign up to request clarification or add additional context in comments.

6 Comments

Are you sure that I'm wrong? Doesn’t read just move a cursor in the stream? It is not explained explicitly here: docs.oracle.com/javase/7/docs/api/java/io/…
@stefan Always reference the official Android docs when dealing with Android issues, not the Oracle ones, there can be subtle differences (there probably aren't in this case, but still) developer.android.com/reference/java/io/InputStream.html#read()
I updated my question. I added a link to the class file of the api I use. Can you take a look at it? Maybe you find the failure...
@stefan Of course you're wrong. If InputStreams behaved as you suggest, nothing would work. And why would they do that? What would be the point? You're clutching at straws. Stop guessing and start debugging.
@stefan so you understand, streams don't generally have a "cursor" except for those classes which provides some restricted random access (e.g. BufferedInputStream or a PushbackInputStream) but these use a limited buffer size... They won't grow indefinitely.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.