有一个处理实时数据的应用程序,并且当某个事件发生时应该发出蜂鸣声。触发事件可以每秒发生多次,并且如果在另一个事件触发时蜂鸣声已经播放,则代码应该忽略它(而不是中断当前的蜂鸣声并开始新的蜂鸣声)。这是基本代码:
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();
}
}
}
prepareProcess方法在开始时运行一次,每次发生触发事件时都会调用playSound方法。我的问题是:我需要关闭clickClip对象吗?我知道我可以添加一个actionListener来监视一个Stop事件,但由于事件经常发生,我担心额外的处理会减慢实时数据的收集速度。
代码似乎运行良好,但我担心的是内存泄漏。上面的代码基于我在搜索网络时发现的示例,但该示例使用了actionListener来专门关闭Clip“以消除在未实现stop方法时可能发生的内存泄漏”。我的程序打算运行几个小时,因此任何内存泄漏都会导致问题。
我会说实话:我不知道如何验证我是否遇到问题。我正在使用Netbeans,运行内存分析器只是给了我一大堆我不知道如何阅读的内容。这应该是该计划的简单部分,我花了几个小时。任何帮助将不胜感激!
迈克尔
答案 0 :(得分:5)
myClip.addLineListener(new LineListener() {
public void update(LineEvent myLineEvent) {
if (myLineEvent.getType() == LineEvent.Type.STOP)
myClip.close();
}
});
或
if (!myClip.isRunning())
myClip.close();
在我的应用程序中(在util.concurrent出现之前编写),这是剪辑关闭机制。
public static final Vector<Clip> vector = new Vector<Clip>();
static final int vector_size = 5;
// typically called before calling play()
static synchronized void consolidate() {
while (vector_size < vector.size()) {
Clip myClip = vector.get(0);
if (myClip.isRunning())
break;
myClip.close();
vector.remove(0);
}
if (vector_size * 2 < vector.size())
System.out.println("warning: audio consolidation lagging");
}
public static void play(final File myFile) {
try {
AudioInputStream myAudioInputStream = AudioSystem.getAudioInputStream(myFile);
final Clip myClip = AudioSystem.getClip();
vector.add(myClip);
myClip.open(myAudioInputStream);
myClip.start();
} catch (Exception myException) {
myException.printStackTrace();
}
}
正如其中一条评论所暗示的那样,它可能会延迟播放新剪辑,但我不记得因为几毫秒的延迟在我的应用程序中并不重要。
答案 1 :(得分:0)
Java中的内存泄漏与即使在其使用寿命结束后仍被引用的对象有关。在许多情况下,这将是由于重复制作50个对象之类的东西,但后来只消除了对其中49个对象的引用。
在你的代码中似乎没有这样的东西。由于prepareProcess()
只运行一次,因此不是很可疑。留下playSound()
,它根本不包含任何对象实例化,更不用说错误的引用消除循环了。
需要注意的是,我不确定你的声音剪辑对象幕后发生了什么,并且很难检查,因为majuscule-C Clip
只是一个界面。但是,除非您使用第三方代码,否则我会非常惊讶地发现泄漏。
长话短说,我不会担心它,除非你真的看到像OutOfMemoryError
这样的东西。