【问题标题】:Java Clip (Sound / Audio) Memory Leak after closing with close()用 close() 关闭后的 Java Clip(声音/音频)内存泄漏
【发布时间】:2009-11-29 21:28:45
【问题描述】:

以下代码创建一个新的音频剪辑,播放它,休眠 3 秒,然后在播放完毕后关闭它。尽管调用了 close(),但每次运行 while 循环时,我都会看到 jvm 的内存使用量随着声音剪辑的大小而增加。

我正在参加一个用 java 编码的游戏,并且正在处理声音。每次播放声音时,我都无法增加我正在使用的内存。

我错过了什么?

import java.io.File;
import javax.sound.sampled.*;

public class ClipLeak{

public static void main(String[] args) throws Exception{
    while(true){
        File soundFile = new File("./sound.wav");
        AudioInputStream sound = AudioSystem.getAudioInputStream(soundFile);

        DataLine.Info info = new DataLine.Info(Clip.class, sound.getFormat());
        Clip clip = (Clip) AudioSystem.getLine(info);
        clip.open(sound);
                    sound.close();

        clip.addLineListener(new LineListener(){
            public void update(LineEvent event){
                if(event.getType() == LineEvent.Type.STOP){
                    event.getLine().close();
                }
            }
        });

        clip.start();
        Thread.sleep(2000);
    }
}
}

【问题讨论】:

    标签: java memory memory-leaks clip


    【解决方案1】:
    Try this
        import java.io.File;
        import javax.sound.sampled.*;
    
        public class ClipLeak{
    
        public static void main(String[] args) throws Exception{
            while(true){
                File soundFile = new File("./sound.wav");
                AudioInputStream sound = AudioSystem.getAudioInputStream(soundFile);
    
                DataLine.Info info = new DataLine.Info(Clip.class, sound.getFormat());
                Clip clip = (Clip) AudioSystem.getLine(info);
                clip.open(sound);
    
    
                clip.addLineListener(new LineListener(){
                    public void update(LineEvent event){
                        if(event.getType() == LineEvent.Type.STOP){
                            event.getLine().close();
                        }
                    }
                });
    
                clip.start();
                Thread.sleep(2000);
                if (clip.isOpen()) {
                 clip.close();
                 sound.close();
                }
            }
        }
        }
    

    【讨论】:

      【解决方案2】:

      如果您确定存在内存泄漏而不是垃圾收集延迟,您可以从关闭和清理您分配的所有资源开始,移除侦听器并将所有引用设置为 null。 (也将File 对象移出循环。)

      如果这没有帮助并且 javadocs 没有提示可以清除什么,您可以触发堆转储以查看哪些对象使用了内存以及它们的根路径是什么。

      【讨论】:

      • 我让循环运行了大约一分钟,看着内存不断攀升。如果它正在被垃圾收集,我应该会在那一刻看到内存减少,对吧?
      • 不一定。 JVM 只在需要时才运行 GC。
      • 这取决于其余代码的繁忙程度,它可能会增加一段时间然后再下降。垃圾收集周期倾向于显示拼图模式。这很正常。话虽如此,您可能想要关闭并清除您使用的资源。
      • "不一定。JVM 只在感觉合适的时候运行 GC。"不,您可以使用 System.gc(); 引起 gc;
      猜你喜欢
      • 2011-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-27
      • 2015-09-21
      • 1970-01-01
      相关资源
      最近更新 更多