views:

27

answers:

1

have an application that processes real-time data and is supposed to beep when a certain event occurs. The triggering event can occur multiple times per second, and if the beep is already playing when another event triggers the code is just supposed to ignore it (as opposed to interrupting the current beep and starting a new one). Here is the basic code:

Clip clickClip

public void prepareProcess() {
    super.prepareProcess();

    clickClip = null;

    try {
        clipFile = new File("C:/WINDOWS/Media/CHIMES.wav");
        ais = AudioSystem.getAudioInputStream(clipFile);
        clickClip = AudioSystem.getClip();
        clickClip.open(ais);

        fileIsLoaded = true;

    } catch (Exception ex) {
        clickClip = null;
        fileIsLoaded = false;
    }
}

public void playSound() {

    if (fileIsLoaded) {

        if ((clickClip==null) || (!clickClip.isRunning())) {

            try {
                clickClip.setFramePosition(0);
                clickClip.start();
            } catch (Exception ex) {
                System.out.println("Cannot play click noise");
                ex.printStackTrace();
            }
        }
    }

The prepareProcess method gets run once in the beginning, and the playSound method is called every time a triggering event occurs. My question is: do I need to close the clickClip object? I know I could add an actionListener to monitor for a Stop event, but since the event occurs so frequently I'm worried the extra processing is going to slow down the real-time data collection.

The code seems to run fine, but my worry is memory leaks. The code above is based on an example I found while searching the net, but the example used an actionListener to close the Clip specifically "to eliminate memory leaks that would occur when the stop method wasn't implemented". My program is intended to run for hours so any memory leaks I have will cause problems.

I'll be honest: I have no idea how to verify whether or not I've got a problem. I'm using Netbeans, and running the memory profiler just gave me a huge list of things that I don't know how to read. This is supposed to be the simple part of the program, and I'm spending hours on it. Any help would be greatly appreciated!

Michael

A: 

Memory leaks in Java have to do with objects that are still being referenced even after their useful lives have ended. In many cases, this will be due to something like repeatedly making 50 objects but only eliminating references to 49 of them later on.

Nothing like that seems to be going on in your code. Since prepareProcess() only runs once, it's not highly suspect. That leaves playSound(), which doesn't contain any object instantiation at all, much less a faulty reference elimination loop.

The caveat is that I'm not sure what goes on behind the scenes in your sound clip object, and it's hard to check because majuscule-C Clip is only an interface. Unless you're using third-party code, though, I'd be very surprised to find a leak there.

Long story short, I wouldn't worry about it unless and until you actually see something like an OutOfMemoryError.

Lord Torgamus
Thanks so much for the response. I agree with you that, based on the code I give, it doesn't seem to be a problem. But (as you mention) I don't know either what is happening behind the scenes of the Clip object. Fooling around more with the Netbeans memory profiler, it appears that a new object is allocated each time the sound is played. However, the Live Object column never increases so I'm assuming this means the garbage collection takes care of it immediately. Strange behavior, but I'll make sure to watch it during testing to make sure it's ok.Thanks again.Michael
Michael