We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Could someone check if the following test code crashes on their computer?
The code is a stripped down skeleton of a data acquisiton program, but it still produces the same OutOfMemoryError after 109 s. Increasing the max. available memory to 1024 kB, its "lifetime" also increases to about 440 s.
(Processing 2.0.3, Win7, 2GB)
Test code:
import processing.net.*;
int port = 10002;
Server myServer;
Client myClient;
int bigByteArraySize = 1000000; // 10^6
byte[] bigByteBuffer = new byte[bigByteArraySize];
byte[] smallByteBuffer = new byte[bigByteArraySize/10];
int startTime;
void setup() {
myServer = new Server(this, port);
myClient = new Client(this, "127.0.0.1", port);
thread("serverWrite");
startTime = millis();
}
void draw() {
if ( myClient.available() > bigByteArraySize ) {
// Read the bytes
myClient.readBytes(bigByteBuffer);
println("elapsed time = " + (millis()-startTime)/1000.0 + " s");
// Print memory usage
printMem();
// Garbage collector - won't help :(
System.gc();
}
}
// Simulate server (data rate < 1 MB/s)
void serverWrite() {
while (true) {
myServer.write(smallByteBuffer);
delay(100);
}
}
// Print memory usage
void printMem() {
int maxMemMB = int(Runtime.getRuntime().maxMemory()/1024/1024);
int totalMemMB = int(Runtime.getRuntime().totalMemory()/1024/1024);
int freeMemMB = int(Runtime.getRuntime().freeMemory()/1024/1024);
println("memory [MB]:" + " max: " + maxMemMB + " | total: " + totalMemMB + " | free: " + freeMemMB);
}
Comments
1024 kB should have been 1024 MB, sorry.
Whoever (benfry?) wrote the Client class in the Network library, had warned of the memory leak I described above.
This is an excerpt from Client.java:
Client starts with a buffer of a decent size:
But whenever it gets full (bufferLast == buffer.length), its size will be doubled. That would be harmless, if after some time bufferLast, the "write index" could not reach the length of the buffer.
bufferLast, the "write index" is rewound when bufferIndex, the "read index" catches up with it or the clear() method clears the buffer. Unfortunately, readBytes(bytebuffer), the method I used in my faulty code will never rewind bufferLast if called after this condition:
That I think explains the memory leak. What is still not clear to me is why - according to the reference - readBytes(bytebuffer) is "more memory and time efficient" than a simple readBytes().