Results 1 to 11 of 11
  1. #1
    cdman52 is offline Member
    Join Date
    Jun 2009
    Posts
    3
    Rep Power
    0

    Default Help I have a memory leak...

    I'm using some software called WireFusion to develop an interactive 3D biology page. Anyway, I have some code here that gets called every millisecond or so, and if the audio isn't currently playing it will start it based on the step the user is at in the 3D animation. The problem is that if you go through the audio enough times java will crash. I could turn the memory up a lot and then the chances of crashing go down but that doesn't solve the problem. Somewhere my objects aren't deleting.

    Here's the class that's causing the problem. I think the problem is in the inport_playAudio function but maybe it's not. I think maybe the stream isn't releasing its resources when I call stream.close(), or maybe I'm not closing it correctly.

    Any help would be great.

    Java Code:
    package wobs.java.player.extension;
    
    import com.wirefusion.player.*;
    import wobs.java.player.JavaWob;
    import wobs.number.player.NumberWob;
    import wobs.bool.player.BoolWob;
    import wobs.text.player.TextWob;
    import wobs.number2d.player.Number2DWob;
    import wobs.color.player.ColorWob;
    import java.awt.*;
    import globals.*;
    import javax.sound.sampled.*;
    import java.io.*;
    import javax.sound.sampled.AudioInputStream;
    
    public class JavaWob118570912 extends JavaWob
    {
       private boolean initialized = false;
       private String audio[];
       private boolean audioOn = false;
       private boolean playing = false;
       Clip clip;
       AudioInputStream stream;
       DataLine.Info info;
       
       public void init()
       {
          if(initialized == false)
             setup();
       }
       
       public void inport_toggleAudio(double arg)
       {
          int togVal = (int)(arg / 1);
          System.out.println("Toggle Audio: " + togVal);
          if(togVal == 1)
             audioOn = true;
          else
          {
             audioOn = false;   
             if(playing)
                clip.stop();   
          }
       }
    
       public void setup()
       {      
          audio = null;
          clip = null;
          stream = null;
          info = null;
          
          audio = new String[GlobalData.clips.length];
          for(int i=0; i < GlobalData.clips.length; i++)
          {
             audio[i] = GlobalData.clips[i];
          }
       }
       
       public void inport_playAudio(double arg)
       {
          int step = (int)(arg / 1)-1;
       
          if(audioOn && playing == false)
          {      
             if(clip != null && clip.isRunning())
             {
                clip.stop();
                clip = null;
             }
             
             try {
               // From file
               if(stream != null)
                  stream.close();
               stream = null;
              
             stream = AudioSystem.getAudioInputStream(getResource(audio[step]).getInputStream());
            
             AudioFormat format = stream.getFormat();
             // Create the clip
            
               info = null;
               
             DataLine.Info info = new DataLine.Info(Clip.class, stream.getFormat(), ((int)stream.getFrameLength()*format.getFrameSize()));
            
             clip = (Clip) AudioSystem.getLine(info);
              
              info = null;
             // Add a listener for line events
             clip.addLineListener(new LineListener()
             {
                public void update(LineEvent evt)
               {
                  if (evt.getType() == LineEvent.Type.STOP)
                 {
                    System.out.println("Stopped.");
                    playing = false;
                    
                    try
                    {                   
                       if(stream != null)
                              stream.close();
                           stream = null;
                        }
                        catch (IOException e)
                       {
                            System.out.println("Problem with the IO. " + e.getMessage());
                            playing = false;
                       }                    
                      }
               }
                });
              
             // This method does not return until the audio file is completely loaded
             clip.open(stream);
             // Start playing
             clip.start();
             playing = true;
           }
             catch (IOException e)
           {
                System.out.println("Problem with the IO. " + e.getMessage());
                playing = false;
           }
             catch (LineUnavailableException e)
             {
                System.out.println("Problem with the line. " + e.getMessage());
                playing = false;
           }
             catch (UnsupportedAudioFileException e)
             {
                System.out.println("Unsupported Audio. " + e.getMessage());
                playing = false;
           }      
          }
       }
       
       public void inport_stopAudio()
       {
          if(playing)
          {
             playing = false;
             clip.stop();
             clip = null;   
             
             try
             {
                if(stream != null)
                  stream.close();
               stream = null;         
             }
             catch (IOException e)
           {
                System.out.println("Problem with the IO. " + e.getMessage());
                playing = false;
           }      
          }   
       }
    }

  2. #2
    cdman52 is offline Member
    Join Date
    Jun 2009
    Posts
    3
    Rep Power
    0

    Default

    Bump.

    Any help?

  3. #3
    Eranga's Avatar
    Eranga is offline Moderator
    Join Date
    Jul 2007
    Location
    Colombo, Sri Lanka
    Posts
    11,371
    Blog Entries
    1
    Rep Power
    20

    Default

    Check the all streams you've used closed in the correct place. Within the code, if any of your stream is no longer use, better to close them. Later you can open them(simplicity based on your design)

    Did you try to call garbage collector manually. Actually we cannot guaranteed that it'll clearup all unnecessary memory, but it will. Just give a try and see.

  4. #4
    Steve11235's Avatar
    Steve11235 is offline Senior Member
    Join Date
    Dec 2008
    Posts
    1,046
    Rep Power
    7

    Default

    So do I. Oh, you mean on your computer...

    Eranga is correct about closing your streams. Also, make sure you don't have circular references, where two objects refer to each other.

    Two last resorts. Use a custom class loader to load the audio classes. After each "session", get rid of the class loader (I don't remember the method). This will unload all the classes it loaded from memory. Get a new class loader and reload to start the next session. If the audio classes use native objects, those objects may be the problem. In that case, at the end of each session, start a new JVM using Runtime.exec() and let the current one end. That will definitely free up resources.

  5. #5
    Eranga's Avatar
    Eranga is offline Moderator
    Join Date
    Jul 2007
    Location
    Colombo, Sri Lanka
    Posts
    11,371
    Blog Entries
    1
    Rep Power
    20

    Default

    Actually most of time these types of errors cause because of endless loops. Those things are not handle automatically with GC.

  6. #6
    Steve11235's Avatar
    Steve11235 is offline Senior Member
    Join Date
    Dec 2008
    Posts
    1,046
    Rep Power
    7

    Default

    I want to correct myself. Circular references, by themselves, don't interfere with gc.

    I saw that you add listeners to the clips. Are you removing the listeners? If not, that would likely prevent the clips from getting gc'ed, even though you null'ed the reference to the clip itself.

  7. #7
    Eranga's Avatar
    Eranga is offline Moderator
    Join Date
    Jul 2007
    Location
    Colombo, Sri Lanka
    Posts
    11,371
    Blog Entries
    1
    Rep Power
    20

    Default

    Ya that's true Steve, to use the GC need a better idea about how to use it different steps. But in this case, it wont harm at all.

  8. #8
    cdman52 is offline Member
    Join Date
    Jun 2009
    Posts
    3
    Rep Power
    0

    Default

    Thank you Steve11235!!!
    I have been working on this (1 day a week) for several weeks!!
    Removing the line listener was the problem. I did that and all of the sudden my memory is back!!

    Thanks.

  9. #9
    Steve11235's Avatar
    Steve11235 is offline Senior Member
    Join Date
    Dec 2008
    Posts
    1,046
    Rep Power
    7

    Default

    Listeners are part of the defining class that are held by class that fires events. The fact that the clip holds a reference seems to be enough to prevent gc.

  10. #10
    flok is offline Member
    Join Date
    Sep 2009
    Location
    Gouda, the Netherlands
    Posts
    24
    Rep Power
    0

    Default

    Quote Originally Posted by Eranga View Post
    Actually most of time these types of errors cause because of endless loops. Those things are not handle automatically with GC.
    So if I have a mainloop like this:

    Java Code:
        void myMethod()
        {
             for(;;)
             {
                   scene s = s.move();
                   // more code
             }
        }
    then the original scene (the previous s so to say) stays in memory?
    Last edited by flok; 09-27-2009 at 04:07 PM. Reason: formatting fix

  11. #11
    Steve11235's Avatar
    Steve11235 is offline Senior Member
    Join Date
    Dec 2008
    Posts
    1,046
    Rep Power
    7

    Default

    I hate to pick, but... I don't like the loop post for two reasons:

    1. The variable "s" will go out of scope each time around the loop. Assuming it was assigned (as presented, it would cause an uninitialized error(?). Thus, the reference is broken each time around the loop.

    2. Defining the variable "s" in a loop causes it to be repeatedly allocated and deallocated, creating a lot of needless activity on the stack. Better to define "s" outside the loop and update it within the loop. The worst than can happen is that "s" will hold a reference to one object.

Similar Threads

  1. java.util.logging.StreamHandler memory leak?
    By toadaly in forum Advanced Java
    Replies: 1
    Last Post: 02-23-2009, 03:46 PM
  2. Replies: 2
    Last Post: 08-21-2008, 08:33 PM
  3. Out of memory
    By mew in forum New To Java
    Replies: 1
    Last Post: 01-20-2008, 09:55 AM
  4. Memory
    By mew in forum CLDC and MIDP
    Replies: 0
    Last Post: 12-28-2007, 12:02 PM
  5. Memory Leak using a Swing Application Project
    By iimasd in forum AWT / Swing
    Replies: 0
    Last Post: 11-27-2007, 11:20 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •