user6036727
user6036727

Reputation:

Audio playing in Java without memory leaks

I have a current system in my game where there's an AudioPlayer class and this holds AudioChannels. I keep getting heap dumps (which I have looked over with MAT) and are directing toward:

com.sun.media.sound.DirectAudioDevice$DirectClip.open(Unknown Source)

The leak in MAT looks like this:

127 instances of "com.sun.media.sound.DirectAudioDevice$DirectClip", loaded by "<system class loader>" occupy 754,011,696 (94.80%) bytes. 

Biggest instances:
•com.sun.media.sound.DirectAudioDevice$DirectClip @ 0xcc5e9f18 - 30,427,248 (3.83%) bytes. 
•com.sun.media.sound.DirectAudioDevice$DirectClip @ 0xce3cf970 - 30,427,248 (3.83%) bytes. 
•com.sun.media.sound.DirectAudioDevice$DirectClip @ 0xdf62fc58 - 30,427,248 (3.83%) bytes. 
•com.sun.media.sound.DirectAudioDevice$DirectClip @ 0xdf741840 - 30,427,248 (3.83%) bytes. 
•com.sun.media.sound.DirectAudioDevice$DirectClip @ 0xe2b7b968 - 30,427,248 (3.83%) bytes. 
•com.sun.media.sound.DirectAudioDevice$DirectClip @ 0xe2b7f2a0 - 30,427,248 (3.83%) bytes. 
•com.sun.media.sound.DirectAudioDevice$DirectClip @ 0xe2c80678 - 30,427,248 (3.83%) bytes. 
•com.sun.media.sound.DirectAudioDevice$DirectClip @ 0xe2c844a8 - 30,427,248 (3.83%) bytes. 
•com.sun.media.sound.DirectAudioDevice$DirectClip @ 0xe59e1d18 - 30,427,248 (3.83%) bytes. 
•com.sun.media.sound.DirectAudioDevice$DirectClip @ 0xec186a20 - 30,427,248 (3.83%) bytes. 
•com.sun.media.sound.DirectAudioDevice$DirectClip @ 0xcc5ea388 - 23,556,720 (2.96%) bytes. 
•com.sun.media.sound.DirectAudioDevice$DirectClip @ 0xcc654850 - 23,556,720 (2.96%) bytes. 
•com.sun.media.sound.DirectAudioDevice$DirectClip @ 0xe1502670 - 23,556,720 (2.96%) bytes. 
•com.sun.media.sound.DirectAudioDevice$DirectClip @ 0xe2b7bdd8 - 23,556,720 (2.96%) bytes. 
•com.sun.media.sound.DirectAudioDevice$DirectClip @ 0xe2b7f688 - 23,556,720 (2.96%) bytes. 
•com.sun.media.sound.DirectAudioDevice$DirectClip @ 0xe2c80ae8 - 23,556,720 (2.96%) bytes. 
•com.sun.media.sound.DirectAudioDevice$DirectClip @ 0xe2c84890 - 23,556,720 (2.96%) bytes. 
•com.sun.media.sound.DirectAudioDevice$DirectClip @ 0xe4363c68 - 23,556,720 (2.96%) bytes. 
•com.sun.media.sound.DirectAudioDevice$DirectClip @ 0xeab00030 - 23,556,720 (2.96%) bytes. 
•com.sun.media.sound.DirectAudioDevice$DirectClip @ 0xcc5eb828 - 23,049,840 (2.90%) bytes. 
•com.sun.media.sound.DirectAudioDevice$DirectClip @ 0xcc655cf0 - 23,049,840 (2.90%) bytes. 
•com.sun.media.sound.DirectAudioDevice$DirectClip @ 0xe14965f8 - 23,049,840 (2.90%) bytes. 
•com.sun.media.sound.DirectAudioDevice$DirectClip @ 0xe1503b10 - 23,049,840 (2.90%) bytes. 
•com.sun.media.sound.DirectAudioDevice$DirectClip @ 0xe2b7d5c0 - 23,049,840 (2.90%) bytes. 
•com.sun.media.sound.DirectAudioDevice$DirectClip @ 0xe2c7edb8 - 23,049,840 (2.90%) bytes. 
•com.sun.media.sound.DirectAudioDevice$DirectClip @ 0xe2c827c8 - 23,049,840 (2.90%) bytes. 
•com.sun.media.sound.DirectAudioDevice$DirectClip @ 0xe2cf37c8 - 23,049,840 (2.90%) bytes. 
•com.sun.media.sound.DirectAudioDevice$DirectClip @ 0xe7746aa0 - 23,049,840 (2.90%) bytes. 
•com.sun.media.sound.DirectAudioDevice$DirectClip @ 0xee91fae0 - 23,049,840 (2.90%) bytes. 

I don't know how this is happening as I am unloading the Clip and AIS as best I can.

This is the code I'm using to play audio:

try {
    AudioInputStream ais = AudioSystem.getAudioInputStream(FileReader.getFile(s));
    clip = AudioSystem.getClip();
    clip.open(ais);
    loaded = true;

    FloatControl g = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
    g.setValue((float)(g.getMinimum() + ((double)(g.getMaximum() - g.getMinimum()) * volume)));

    if (loops) {
        clip.loop(Clip.LOOP_CONTINUOUSLY);
    } else {
        clip.start();
    }

    ais.close();
    clip.drain();
} catch (Exception e) {
    e.printStackTrace();
}

Upvotes: 0

Views: 394

Answers (1)

Andrew Regan
Andrew Regan

Reputation: 5113

You aren't closing your audio clips. As soon as you're free and able to, you should try to close them:

if (clip.isOpen()) {
    clip.close();
}

Obviously this may involve you doing more work to track the lifecycle of the clip(s) so you can be sure they can be released in a way that makes sense for your application.

See also:

Upvotes: 1

Related Questions