ddf / Minim

A Java audio library, designed to be used with Processing.
http://code.compartmental.net/tools/minim
GNU Lesser General Public License v3.0
668 stars 136 forks source link

FilePlayers causing memory leak? #78

Open jeraman opened 6 years ago

jeraman commented 6 years ago

Hello,

It seems that instantiating FilePlayers over time may be causing a memory leak on Java Heap (ie. OutOfMemoryError on Processing IDE). Here's an example that causes problem after some seconds:

void draw() {
  FilePlayer filePlayer = new FilePlayer(minim.loadFileStream("123go.mp3"));
  filePlayer.close();
  filePlayer = null;
}

Note that I close all instances I create, so in theory Garbage Collector should take care of this trash and no leaks should happen.

As a contrast, I've replaced the FilePlayer by an AudioSample instance. In this case, no problem occurs and the Heap is kept under control (as checked on VisualVM):

void draw() {
  AudioSample sample = minim.loadSample("123go.mp3", 512);
  sample.trigger();
  sample.stop();
  sample.close();
  sample = null;
}

Am I missing something? Or is this a bug?

jeraman commented 6 years ago

I found out the cause.

The function minim.loadFileStream() stores a copy of the loaded AudioRecordingStream in a vector called streams (see line 599 here). Thus, the reference for the AudioRecordingStream is never lost, and Garbage Collector can't delete it.

To avoid the problem, just load the AudioRecordingStream outside the draw loop:

AudioRecordingStream file = minim.loadFileStream("123go.mp3")

void draw() {
  FilePlayer filePlayer = new FilePlayer(file);
  filePlayer.close();
  filePlayer = null;
}

Problem solved, so I'm closing the issue.

ddf commented 6 years ago

I do consider this a bug. Minim hangs on to AudioRecordingStream objects so that it can close them automatically for Processing users when the sketch exits. It should not be hanging on to streams that the user closes explicitly. AudioPlayer and AudioSample handle this in their close methods, but FilePlayer doesn't (technically, can't with current code).

ddf commented 5 years ago

Just note that the commits above address the issue of Minim itself hanging on to AudioRecordingStream references after a FilePlayer has been closed, but when using VisualVM it seemed be to be the case that there was still a slow leak occurring if loadFileStream is used repeatedly as in your original example. As far as I can tell, there is not a leak in the Minim codepath, but maybe there is one in the mp3spi code somewhere. I need to run the same test with AudioSample to see if it produces the same behavior.