OutOfMemoryError при использовании Clip java

Решено: Я решил это!! Мне пришлось увеличить размер кучи свойств моего проекта в среде netbeans, а не в самой конфигурации среды netbeans.

У меня есть очень простое игровое приложение, я использую объект Clip из пакета javax.sound.sampled для воспроизведения фоновой музыки (файл формата mp3 длиной почти 9 м и размером 8 МБ). Я преобразовал его в файл wav и стало 87мб >_‹. И у меня есть небольшие файлы wav, которые я использую для кнопок. Проблема в том, что я получаю OutOfMemoryError каждый раз, когда завершаю свою программу. Я сделал приложение, которое имитирует ту же проблему, только если вы щелкаете короткие клипы несколько раз после того, как сначала щелкнете файл длинной волны, а затем нажмете кнопку «Завершить», чтобы завершить его, а затем я получаю эту ошибку. Однако я не знаю, как предоставить те же файлы wav другим, чтобы они могли попробовать и протестировать этот образец.

import javax.swing.*;
import javax.sound.sampled.*;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
public class ClipClass extends JPanel implements ActionListener{
private JButton longClip, shortClip1,shortClip2,quit;
public ClipClass(){
    setLayout(new GridLayout(2,2,0,0));
    longClip = new JButton("Play long wav");
    shortClip1 = new JButton("Play short wav1");
    shortClip2 = new JButton("Play short wav2");
    quit = new JButton("Terminate");
    add(longClip);
    add(shortClip1);
    add(shortClip2);
    add(quit);
    longClip.addActionListener(this);
    shortClip1.addActionListener(this);
    shortClip2.addActionListener(this);
    quit.addActionListener(this);
}
public synchronized void playSound(final String url) {
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            try {
                Clip clip = AudioSystem.getClip();
                AudioInputStream inputStream = AudioSystem.getAudioInputStream(new File(url));
                clip.open(inputStream);
                clip.start();
                clip.addLineListener(new LineListener() {
                    @Override
                    public void update(LineEvent evt) {
                        if (evt.getType() == LineEvent.Type.STOP) {
                            evt.getLine().close();
                        }
                    }
                });
            } catch (Exception e) {
            }
        }
    });
}
public static void main(String[] args){
    JFrame frame = new JFrame("SampleSoundOOME");
    ClipClass pane = new ClipClass();
    frame.setContentPane(pane);
    frame.setVisible(true);
    frame.pack();
}

@Override
public void actionPerformed(ActionEvent e) {
    if(e.getSource()==longClip){
        playSound("C:/Users/Sony/Documents/NetBeansProjects/Sphere Break/Trance.wav");
    }if(e.getSource()==shortClip1){
        playSound("C:/Users/Sony/Documents/NetBeansProjects/Sphere Break/KDE_Window_Sticky.wav");
    }if(e.getSource()==shortClip2){
        playSound("C:/Users/Sony/Documents/NetBeansProjects/Sphere Break/KDE_Window_Iconify.wav");
    }if(e.getSource()==quit){
        System.exit(0);
    }
}
}

person katrina    schedule 29.01.2013    source источник
comment
Вместо того, чтобы использовать все операторы if, что не совсем объектно-ориентированно, вы можете использовать вложенные классы или новый ActionLister, а затем перезаписать метод actionPerformed.   -  person maffo    schedule 29.01.2013
comment
попробуйте использовать DiskFile вместо File. Я не уверен в этом случае, но в некоторых других случаях это экономит много памяти.   -  person dinesh707    schedule 29.01.2013
comment
@PoiXen: Спасибо за предложения (в следующий раз я попробую это в небольших приложениях), но в моем реальном приложении у меня есть кнопка массива (это для игровой механики), поэтому я использую операторы if внутри циклов for в методе mouseClicked.   -  person katrina    schedule 29.01.2013


Ответы (2)


Причина этого в том, что ваша программа использует слишком много памяти, превышающей назначенный вами размер кучи (или размер по умолчанию). Утечка памяти также может быть причиной этого. Вы можете помочь сборщику мусора Java, аннулировав все ваши ссылки. В противном случае вы можете установить размер кучи через -Xmx256m, где m = Megabyte.

person Michael 'Maik' Ardan    schedule 29.01.2013
comment
То же, что и ответ выше, и у меня тот же комментарий - person katrina; 29.01.2013
comment
Какой размер кучи вы выделили? - person Michael 'Maik' Ardan; 29.01.2013
comment
это строки, в которых я должен изменить размер кучи?-› netbeans_default_options=-J-client -J-Xss2m -J-Xms32m -J-XX:PermSize=32m -J-Dapple.laf.useScreenMenuBar=true - J-Dapple.awt.graphics.UseQuartz=true -J-Dsun.java2d.noddraw=true -J-Dsun.zip.disableMemoryMapping=true -›››› что мне не хватает или что я должен изменить (по как я уже удалил сделанное изменение, которое было таким: -J-XX-MaxPermSize=500m - person katrina; 29.01.2013

пожалуйста, проверьте размер кучи JVM, исходя из размеров файлов .wav памяти, выделенной для кучи JVM, может быть недостаточно.

Увеличьте кучу jvm, используя: java -Xmx** - где находится память, которую вы можете выделить

Также в виде исключения:

catch (Exception e) {
           //close `inputStream` 
           // close `clip`
}
person TheWhiteRabbit    schedule 29.01.2013
comment
Я пробовал использовать это решение: wiki.netbeans.org/FaqSettingHeapSize, но это не сработало. - person katrina; 29.01.2013
comment
Я пробовал использовать это решение: wiki.netbeans.org/FaqSettingHeapSize, но это не сработало. Кроме того, мне пришлось вынуть эти 2 объекта в качестве общедоступного члена класса, чтобы иметь возможность закрыть его в улове. Что именно это сделает с процессом? Также часть, где я добавил LineListener, представляет собой код, который я не совсем понимаю, но я знаю, что он решил мою ошибку OutOfMemoryError, которая приводит к сбою приложения. - person katrina; 29.01.2013