Link to home
Start Free TrialLog in
Avatar of Virupaksha
Virupaksha

asked on

How to deallocate a memory in java

i am getting OutOfMemory error while executing a program.
my program deals with over 15 MB of data, which will be displayed in different kinds of graph.
other than calling garbage collecter explicitly is there any way of deallocating memory.
Avatar of Tommy Braas
Tommy Braas
Flag of Australia image

The short answer is; No.

You might want to use a tool like OptimizeIt!, by Borland, to find the 'hot spots' in your code.

Do you do a lot of string manipulations? If so, even if they are not that many, the following guide lines might help;

When appending strings, use StringBuffer instead of using '+' to add strings.

In some instances it might make sense to copy the contents of a String into a byte array, and then manipulate the information in the array, to finally create a new String.

The String class is immutable, effectively meaning that every time you perform an operation on a String object, a new copy of it will be created, with the changes applied to it.

The StringBuffer class is like a mutable String. Most of the operations you would perform on a StringBuffer does not create new String (but of course, some do, luckily it's quite obvious which ones do). The disadvantaged of using th e StringBuffer class is that it is not a drop-in replacement for String.

Good luck!
Avatar of Virupaksha
Virupaksha

ASKER

i think i am not dealing much with strings,
i think it may be because i am allocating memory for arrays
such as
  JPanel panelArray[] = new JPanel[20];
  TBarGraph barArray[] = new TBarGraph[40];
If you are allocating a lot of those arrays, that would certainly explain it! Usually, you will get OutOfMemory exceptions when one of two things occur:

-> You are allocating memory so fast that the JVM heap allocator can't keep up. If you are allocating all your memory up front, maybe you should allocate the memory as it is needed.

-> You are running out of free heap space. The solution to that problem, would be to allocate more memory to the JVM. Look up the commandline switches for your specific JVM.

It would also help if you could post some sample code.
i tried the command line option
mx256m for extending the heap size for JVM, but the problem still exists as the graphs are increased.
 is it possible to allocate the memory as required for the arrays i have mentioned, maintaining the same purpose.
I would think so. It all depends on how your code is structured in terms of how and when memory is allocated.

Also, if there isn't reallt a fixed size for the arrays, maybe you should use a LinkedList, which will grow as you add objects to it. That way the memory allocation is spread out.

How many arrays and of which sizes are you allocating? Are you populating all the indexes in those arrays with objects?

Is there perhaps another, less memory intensive, way that you could implement the drawing of the graphs? Are you using 20 different graphs simultaneously? Or are you using the JPanels as containers for one or maybe two graph elements?

If you are using a lot of graphs on-screen simutaneously, maybe the design of the UI for the application should be re-designed.

Are you re-creating the JPanels when the graphs change? Once again, some sample code would help.

Basically, when dealing with UI elements, try to re-use the existing objects, rather than disposing and re-instantiating them again.
i am giving the code which draws the bar graph.

    public void barGraph(String parameters,int flag){
      String ss[] = new String[3];
      ss[0] = "actual_values";
      ss[1] = "difference";
      ss[2] = "accumulate";
      selected1 = new String();
      JFrame parFrame = new JFrame();
      int iCount = 0;
      JPanel t1 = new JPanel();
      JPanel t2 = new JPanel();

      String      archName = getArchName(getFirstParameter(parameters));
      Object[]  choices = traceData.getStates(archName);
      TRadioChoiceDialog stateDialog =  new TRadioChoiceDialog(parentFrame, choices);
      JPanel dump = new JPanel();
      if(stateDialog.show()){

          TRadioChoiceDialog11 stateDialog1 =  new TRadioChoiceDialog11(parFrame, ss);
          if(stateDialog1.show()){
          selected1 = new String(stateDialog1.selected());
            }

          String selected = new String(stateDialog.selected());
          StringTokenizer tok = new StringTokenizer( selected, " " );
          while( tok.hasMoreTokens() ){
            if(iCount != 0)
            flag = 0;
            String currState = tok.nextToken();
            StringTokenizer tok1 = new StringTokenizer( parameters, " " );
            while( tok1.hasMoreTokens() ){
            String parameters1 = tok1.nextToken();
            if((flag == 1) || (pCount == 0)){
            if(pCount == 0)
            flag = 1;
            //panel = new JPanel();
            panel            = new TDrawView();
            parentPanel = new JPanel();
            parentPanel.setLayout(new BorderLayout());
            parentPanel.add(panel, BorderLayout.CENTER);
            eventBar = new TEventBar(new Dimension(screenSize.width*3/4,30),traceData);
            int id = getTabCount();
            eventArray[id] = eventBar;
            count++;
            parentPanel.add(eventBar,BorderLayout.SOUTH);
            parentPanel.setVisible(true);
            panelArray[id] = parentPanel;
            pCount++;
            iCount++;
            parentScroll = new JScrollPane(parentPanel,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
            parentScroll.setVisible(true);
            parentScroll.updateUI();
            parentScroll.addMouseListener(this);
            myAdjustmentListener listener = new myAdjustmentListener();
            parentScroll.getVerticalScrollBar().addAdjustmentListener(listener);
            Object ra[] = traceData.getReportsList();
            width = (600/100) * ra.length;
            panel.setPreferredSize(new Dimension(width,120));
            panel.revalidate();

            vertPanel = new JPanel();
            graphPanel = new JPanel();
            JPanel tempPanel = new JPanel();
            tempPanel.setPreferredSize(new Dimension(60,eventBar.getPreferredSize().height + 20));
            tempPanel.revalidate();
            vertPanel.setLayout(new BorderLayout());
            vertPanel.add(tempPanel,BorderLayout.SOUTH);
            vertPanel.add(graphPanel,BorderLayout.CENTER);
            graphPanel.setVisible(true);
            graphPanel.setPreferredSize(new Dimension(60,120));
            graphPanel.revalidate();
            grandPanel = new JPanel();
            grandPanel.setLayout(new BorderLayout());
            grandPanel.add(vertPanel,BorderLayout.WEST);
            grandPanel.add(parentScroll,BorderLayout.CENTER);
            grandPanel.setVisible(true);

            addTabTitle(getParamName(getFirstParameter(parameters)) + "-" + currState ,currTabIndex=getTabCount());
            addTab(new String(getTabTitle(currTabIndex)), grandPanel);
            tabSize ts = new tabSize();
            ts.graphCount = 1;
            ts.width = width;
            ts.height = 120;
            tabArray[currTabIndex] = ts;
            }
            else {
            dump = (JPanel)getPanel(getSelectedIndex());
            panel=(TDrawView)dump.getComponent(0);//(JPanel)dump.getComponent(0);
            t1 = (JPanel)getSelectedComponent();
            t2 = (JPanel)t1.getComponent(0);
            graphPanel = (JPanel)t2.getComponent(1);
            currTabIndex = getSelectedIndex();
            tabArray[currTabIndex].graphCount += 1;
            if(tabArray[currTabIndex].graphCount > 2)
            {
            tabArray[currTabIndex].height += 60;
            panel.setPreferredSize(new Dimension(tabArray[currTabIndex].width,tabArray[currTabIndex].height));
            panel.revalidate();
            graphPanel.setPreferredSize(new Dimension(60,tabArray[currTabIndex].height));
            graphPanel.revalidate();

            }
            }

            viewArray.clear();
            setupBarGraphView( eventBar.getBeginCycle(), eventBar.getEndCycle(),parameters1, currState, 0, flag);
            vertPanel.updateUI();
            panel.updateUI();
            ch1 = new check();
          }
            }
      }

    }

    class myAdjustmentListener implements AdjustmentListener{

    public void adjustmentValueChanged(AdjustmentEvent e){
      panel.updateUI();
      }
      }
i am giving the code which draws the bar graph.

    public void barGraph(String parameters,int flag){
      String ss[] = new String[3];
      ss[0] = "actual_values";
      ss[1] = "difference";
      ss[2] = "accumulate";
      selected1 = new String();
      JFrame parFrame = new JFrame();
      int iCount = 0;
      JPanel t1 = new JPanel();
      JPanel t2 = new JPanel();

      String      archName = getArchName(getFirstParameter(parameters));
      Object[]  choices = traceData.getStates(archName);
      TRadioChoiceDialog stateDialog =  new TRadioChoiceDialog(parentFrame, choices);
      JPanel dump = new JPanel();
      if(stateDialog.show()){

          TRadioChoiceDialog11 stateDialog1 =  new TRadioChoiceDialog11(parFrame, ss);
          if(stateDialog1.show()){
          selected1 = new String(stateDialog1.selected());
            }

          String selected = new String(stateDialog.selected());
          StringTokenizer tok = new StringTokenizer( selected, " " );
          while( tok.hasMoreTokens() ){
            if(iCount != 0)
            flag = 0;
            String currState = tok.nextToken();
            StringTokenizer tok1 = new StringTokenizer( parameters, " " );
            while( tok1.hasMoreTokens() ){
            String parameters1 = tok1.nextToken();
            if((flag == 1) || (pCount == 0)){
            if(pCount == 0)
            flag = 1;
            //panel = new JPanel();
            panel            = new TDrawView();
            parentPanel = new JPanel();
            parentPanel.setLayout(new BorderLayout());
            parentPanel.add(panel, BorderLayout.CENTER);
            eventBar = new TEventBar(new Dimension(screenSize.width*3/4,30),traceData);
            int id = getTabCount();
            eventArray[id] = eventBar;
            count++;
            parentPanel.add(eventBar,BorderLayout.SOUTH);
            parentPanel.setVisible(true);
            panelArray[id] = parentPanel;
            pCount++;
            iCount++;
            parentScroll = new JScrollPane(parentPanel,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
            parentScroll.setVisible(true);
            parentScroll.updateUI();
            parentScroll.addMouseListener(this);
            myAdjustmentListener listener = new myAdjustmentListener();
            parentScroll.getVerticalScrollBar().addAdjustmentListener(listener);
            Object ra[] = traceData.getReportsList();
            width = (600/100) * ra.length;
            panel.setPreferredSize(new Dimension(width,120));
            panel.revalidate();

            vertPanel = new JPanel();
            graphPanel = new JPanel();
            JPanel tempPanel = new JPanel();
            tempPanel.setPreferredSize(new Dimension(60,eventBar.getPreferredSize().height + 20));
            tempPanel.revalidate();
            vertPanel.setLayout(new BorderLayout());
            vertPanel.add(tempPanel,BorderLayout.SOUTH);
            vertPanel.add(graphPanel,BorderLayout.CENTER);
            graphPanel.setVisible(true);
            graphPanel.setPreferredSize(new Dimension(60,120));
            graphPanel.revalidate();
            grandPanel = new JPanel();
            grandPanel.setLayout(new BorderLayout());
            grandPanel.add(vertPanel,BorderLayout.WEST);
            grandPanel.add(parentScroll,BorderLayout.CENTER);
            grandPanel.setVisible(true);

            addTabTitle(getParamName(getFirstParameter(parameters)) + "-" + currState ,currTabIndex=getTabCount());
            addTab(new String(getTabTitle(currTabIndex)), grandPanel);
            tabSize ts = new tabSize();
            ts.graphCount = 1;
            ts.width = width;
            ts.height = 120;
            tabArray[currTabIndex] = ts;
            }
            else {
            dump = (JPanel)getPanel(getSelectedIndex());
            panel=(TDrawView)dump.getComponent(0);//(JPanel)dump.getComponent(0);
            t1 = (JPanel)getSelectedComponent();
            t2 = (JPanel)t1.getComponent(0);
            graphPanel = (JPanel)t2.getComponent(1);
            currTabIndex = getSelectedIndex();
            tabArray[currTabIndex].graphCount += 1;
            if(tabArray[currTabIndex].graphCount > 2)
            {
            tabArray[currTabIndex].height += 60;
            panel.setPreferredSize(new Dimension(tabArray[currTabIndex].width,tabArray[currTabIndex].height));
            panel.revalidate();
            graphPanel.setPreferredSize(new Dimension(60,tabArray[currTabIndex].height));
            graphPanel.revalidate();

            }
            }

            viewArray.clear();
            setupBarGraphView( eventBar.getBeginCycle(), eventBar.getEndCycle(),parameters1, currState, 0, flag);
            vertPanel.updateUI();
            panel.updateUI();
            ch1 = new check();
          }
            }
      }

    }

    class myAdjustmentListener implements AdjustmentListener{

    public void adjustmentValueChanged(AdjustmentEvent e){
      panel.updateUI();
      }
      }
Ok, I believe that the root of your problem is that objects are created faster than additional heap memory can be allocated. The JVM doesn't use all the memory that it has been allocated, it simply increases the heap size available to your application as needed.

There are several places in your code that are creating objects that aren't really needed. You are also creating a lot of strings on the heap. You should be able to change most of your aStringVar = new String(otherStringVar); to simply aStringVar = otherStringVar;

A couple of questions:
-> how many times on average does the inner loop execute?
-> is there a way for you to use less UI widgets?
Orangehead911, you have made a couple false statements.  First, I have had applications that started up with 2M of heap, and I allocated over 200M, and the allocation look less than 2 seconds and didn't cause any exceptions.  Memory is allocated synchronously.
Secondly, multiple strings that are the same are only ever stored once.  You can easily create a test program to show that is ture.
brian
thanks for the information.
i think inner loop executes at max 5 times.
i didn't get the second question.
bkrahmer,

Good for you! I have had several memory related issues where memory hasn't been allocated fast enough, and an OutOfMemoryException has resulted, even when the maximum heap size was set to 256M. Furthermore, if you're arguments were true, our friend Virupaksha wouldn't have an OutOfMemoryException, now would he?

So let's focus on helping him.
What I meant with my second question, was if it would be possible for you to decrease the number of panels created for the UI. A widget is a visible GUI component. If that is possible, you would probably decrease the amount of memory needed by your application.

Does the exception occur at the same line of code every time?  Would it be at all possible for you to post the full exception with the full stack trace?
You can download OptimizeIt!, from Borland, at the following address. They have a free trial version;

http://www.borland.com/optimizeit/

There is also Sitraka's JProbe at http://www.sitraka.com/software/jprobe/

Either of those tools would be able to help you pin point the problem.
thanks for the site address, so that i can make use of them in dealing with my problem.
orangehead911, I'm not trolling here, I'm stating that you are making false statements.  I'm being objective.  I'd love to admit that I'm wrong, so please provide a test program that shows this problem.  That will be great evidence for a bug report to file with Sun.
brian
Actually, I was curious, so I did it for you.  Ran fine on my system. (java -Xmx256m MemoryTest)

public class MemoryTest
{
   public static void main(String args[])
   {
      MemoryTest.createMemorySlow();
      System.gc();
      MemoryTest.createMemoryFast();
      try
      {
         Thread.sleep(5000);
      }catch (Exception e) { e.printStackTrace(); }
   }

   public static void createMemorySlow()
   {
      char data[];

      try
      {
         for (int i=0; i<100; i++)
         {
            data = new char[i * 1000000];
            Thread.sleep(250);
         }
      }catch (Exception e) { e.printStackTrace(); }
   }

   public static void createMemoryFast()
   {
      char data[];

      try
      {
         data = new char[100000000];
      }catch (Exception e) { e.printStackTrace(); }
   }

}
bkrahmer, i am sorry for going off the deep end before.

What I was trying to convey is that, regardless of how nice things look in theory, we still have to deal with the reality of things. Making a statement like "I've never had that problem", doesn't mean the problem doesn't exist, and it doesn't aid in the solution of the problem at hand.

Another interesting piece of information would be which version of the JDK is being used. Virupaksha? bkrahmer?
i am using JDK1.4.0
ASKER CERTIFIED SOLUTION
Avatar of Tommy Braas
Tommy Braas
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
orangehead911, I said that you made false statements, only one of which you refuted.  I made a test program which shows the other point.  Instead of trying to cover your tracks by saying things like "Making a statement like 'I've never had that problem', doesn't mean the problem doesn't exist", and trying to make me look like a fool, why don't you back your theories up with some proof?  The things that really don't aid in the solution of the problem at hand is giving out false advice, which I believe I have proven that you have done.  I'm not offering this information to irritate you, or as a 'flame', so please don't be offended.  If you can prove me wrong, I'm all for seeing the proof.

brian
I think that having this discussion in this forum is most inappropriate. I was under the impression that we were trying to help Virupaksha with his problem, as best we can. I see now that apparently you are not of that persuasion, and would prefer to badger me.

Regarding the String class. Yes, it is RECOMMENDED that there is a string pool in place in the JVM, it is NOT however a requirement, so, no guarantees as far as that goes.

Below is an example getting an OutOfMemoryException...wonder why the exception exists at all...hmmm...


import java.util.*;
import javax.swing.*;

public class OutOfMemory
{
     
   /** Creates a new instance of OutOfMemory */
   public OutOfMemory()
   {
      Vector vec = new Vector();
      for(int i=0; i<100000; i++)
      {
         vec.addElement(new JFrame("it will crash " + i));
      }
   }
     
   public static void main(String[] args)
   {
      new OutOfMemory();
   }
     
}
Virupaksha, I am very sorry that this thread has taken the turn it has. Please forgive me. I shall be happy to help you in the future, but I will not post any more comments on this thread.

\t
in what sense the new version of java helps me, will it solve my problem or whether the new version takes care of OutOfMemory error.
I consider discussing software operational theories as scientific debates until they degenerate into name-calling.  I don't think that I have said anything out of line, but would like to add that nobody was debating the fact that OutOfMemory exceptions can happen.  Each JVM (that I've used) has default maximum memory usage values hard-coded.  Of course you are going to get exceptions when you've used all your memory.  My point was that I don't believe OOM exceptions happen from using memory 'too fast.'  Nor have I seen it happen, nor have I seen test code that proves it will.  Thank you.

brian
i have applied the methods such as changing the arrays to LinkedList, removing unnecessary objects, and assigning string variables directly instead of using new String().
i think now i am not getting OutOfMemory error but the application has become slow.
Virupaksha:
This old question needs to be finalized -- accept an answer, split points, or get a refund.  For information on your options, please click here-> http:/help/closing.jsp#1 
EXPERTS:
Post your closing recommendations!  No comment means you don't care.
Avatar of TimYates
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:

Accept orangehead911's comment as answer.

Please leave any comments here within the next seven days.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

TimYates
EE Cleanup Volunteer