简体   繁体   中英

java.lang.OutOfMemoryError: Java heap space, How can i free memory?

Here is the error

Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
at com.sun.media.sound.JavaSoundAudioClip.readStream(JavaSoundAudioClip.java:328)
at com.sun.media.sound.JavaSoundAudioClip.loadAudioData(JavaSoundAudioClip.java:307)
at com.sun.media.sound.JavaSoundAudioClip.<init>(JavaSoundAudioClip.java:93)
at sun.applet.AppletAudioClip.createAppletAudioClip(AppletAudioClip.java:108)
at sun.applet.AppletAudioClip.<init>(AppletAudioClip.java:49)
at java.applet.Applet.newAudioClip(Applet.java:279)
at tetris.TetrisAudioPlayer.<init>(TetrisAudioPlayer.java:31)
at tetris.GamePanel.<init>(GamePanel.java:181)
at tetris.TetrisPanelsController.actionPerformed(TetrisPanelsController.java:155)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2028)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2351)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
at java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:272)
at java.awt.Component.processMouseEvent(Component.java:6375)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
at java.awt.Component.processEvent(Component.java:6140)
at java.awt.Container.processEvent(Container.java:2083)
at java.awt.Component.dispatchEventImpl(Component.java:4737)
at java.awt.Container.dispatchEventImpl(Container.java:2141)
at java.awt.Component.dispatchEvent(Component.java:4565)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4619)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4280)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4210)
at java.awt.Container.dispatchEventImpl(Container.java:2127)
at java.awt.Window.dispatchEventImpl(Window.java:2482)
at java.awt.Component.dispatchEvent(Component.java:4565)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:684)
at java.awt.EventQueue.access$000(EventQueue.java:85)
at java.awt.EventQueue$1.run(EventQueue.java:643)
at java.awt.EventQueue$1.run(EventQueue.java:641)

Description of the problem: in the same frame I switch between JPanels, one of them has an Audioclip, if I switch back and forth between this JPanel and another I get this error. I want to free the memory from the JPanel with the Audioclip when I quit it, but seems that assigning null to it doesn't work, any idea? PS The AudioClip class extends JApplet, maybe it is the cause of the problem?

As requested here is the portion of code that "leaks": This is the AudioClip

import java.applet.*;
import javax.swing.*;
import java.net.*;


public class TetrisAudioPlayer extends JApplet {

private AudioClip song; // Sound player

private URL songPath; // Sound path

private boolean playing;

public TetrisAudioPlayer(String filename) {

    try {

        //songPath = new URL(getCodeBase(),filename); // Get the Sound URL

        songPath= this.getClass().getResource(filename);

        song = Applet.newAudioClip(songPath); // Load the Sound
    }

    catch(Exception e){} // Satisfy the catch

}

public void playSound() {
    song.loop(); // Play
    playing=true;
}

public void stopSound() {
    song.stop(); // Stop
    playing=false;
}

public void playSoundOnce() {
    song.play(); // Play only once
    playing=true;
}

public boolean playing(){
    return playing;
}
}

And this is how I change the JPanels, gamePanel is the JPanel wich contains the AudioClip, the error occur only with the AudioClip, without it there is no problem with this code.

        tetrisFrame.getContentPane().removeAll();
        tetrisFrame.getContentPane().invalidate();

        gamePanel=null;

        mainMenuPanel= new MainMenuPanel(this);
        tetrisFrame.getContentPane().add(mainMenuPanel);
        tetrisFrame.getContentPane().validate();
        tetrisFrame.getContentPane().repaint();

Have you tried by setting the JVM arguments with
1. -Xms as the initial size of the heap
2. -Xmx which sets the maximum size of the heap

Increase the heap value based on your RAM

Example:

-Xms512m 
-Xmx1024m

Java -Xmx1024m ......

You might have to assign more memory. Assigning an object to null just marks it to be cleared by the gc.

Have a look at this link

Call below method in onDestroy() or onPause()

Runtime.getRuntime().runFinalization();
Runtime.getRuntime().gc();
System.gc();

But java internally call System.gc() method this is not correct way to free memory , but using above code memory was clear

How to free memory in java:

public void freememory(){
    Runtime basurero = Runtime.getRuntime(); 
    basurero.gc();
}

Call this twice to get better results.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM