?
Solved

JVM - Catch Exceptions

Posted on 2005-03-10
14
Medium Priority
?
225 Views
Last Modified: 2013-12-29
Hi,
I have written a Java Application using JBuilder.  Lately every now and again it is randomly stopping - when it should execute for 5 hours uninterrupted.

I then executed the application from JBuilder in debug mode to understand if any uncaught exceptions are being thrown.  I found that the exception

java.lang.OutOfMemoryError

was being thrown.  I then used Optimizeit to improve its use of memory and reduced the use from 90MB to 60MB.  The application now does not through an error on the development computer.  However when I am running it on the production server it continues to stop.

I think this is still the Out Of Memory error as the production server is executing MS SQL which is using 1.5GB of the available 2GB of memory.  The server has the following config:

Windows Prof.
1 Hard Disk partitioned into two C:/ & D:/  with a page file set on C:/ (Max 4GB)
F Drive - RAID Array with no Page File.
2 GB Physical Memory.

My questions are these:

1.  How can I catch the exception java.lang.OutOfMemoryError error as it seems to be thrown from JVM and not my code.  I would like to confirm that indeed this is the issue on the server (which does not have JBuilder)

2. How can I prevent this issue from happening.  I have a page file manually set on C:/ should I got for "System managed Size"???  

Thanks
Angus
0
Comment
Question by:amacfarl
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 4
  • 3
  • +1
14 Comments
 
LVL 5

Expert Comment

by:ashok3sep
ID: 13503933
increase the heap size:

java -Xmx<size>

Regards,

Freedom
0
 
LVL 5

Expert Comment

by:ashok3sep
ID: 13503995
How did you optimised from 90 mb to 60 mb.........

0
 
LVL 14

Expert Comment

by:sudhakar_koundinya
ID: 13504011
Increasing the memory size may help us on development side, but on production server, hosting people may not give us support to increase the heap size.

So what do you need to do is

put  the code in try catch block and if you get the exception, log the values into database for which you get the exception and later execute them by some other means.

try{
  << CODE>>
}
catch(Throwable e)
{
  if(e instance of  java.lang.Throwable)
  {
            <<log the values>>
            <<clean unwanted objects>>
            << restart the method again>>  
  }
}


But note that,

1. whenever you have acieved the required functionality with particular object, then clean it/nullify the object
say something like myobject=null;

2.  don't maintain maximum variables at class level.
3.  use them at method level only. once method is finished they will go to garbage collector
4. on execution flow, if you think  particlular variable is no where used after it's usage, try to use with some other executions. This can avoid creation  of old variables

Regards
Sudhakar
 
   
0
Optimize your web performance

What's in the eBook?
- Full list of reasons for poor performance
- Ultimate measures to speed things up
- Primary web monitoring types
- KPIs you should be monitoring in order to increase your ROI

 
LVL 2

Author Comment

by:amacfarl
ID: 13504014
I had been declaring a number of arrays which were not always being used (String[][] size 40,000+).  So I changed the handling of String objects, only declaring what I was using.

so for example
java -Xmx4028 would set the heap size to 4GB?

also, does this need to be set every time the computer/server starts?  How can I make it a perm change?  How can I find out the current heap size.

Also, any idea how I can catch/view JRE exceptions?

Thanks
0
 
LVL 14

Expert Comment

by:sudhakar_koundinya
ID: 13504027
I had done Small Mistake

It should be

try{
  << CODE>>
}
catch(Throwable e)
{
  if(e instance of  java.lang.OutOfMemoryError)
  {
            <<log the values>>
            <<clean unwanted objects>>
            << restart the method again>>  
  }
}
0
 
LVL 14

Expert Comment

by:sudhakar_koundinya
ID: 13504046
declaring two dimensional array with such huge sizes is poor methodology.

you should able to get them on fly.

Anyhow can you post corresponding code, so that i can help you

Regards
Sudhakar
0
 
LVL 2

Author Comment

by:amacfarl
ID: 13504058
thanks for your responses!  much appreciated

the issue is that there is no trace provided.  Therefore there is no specific code which I can surround in a try & catch to manage the exception.

That is why I am having such an issue with this problem - as the error could be thrown from any of the 100 of classes.

Any other suggestions?
0
 
LVL 14

Expert Comment

by:sudhakar_koundinya
ID: 13504066
ok,

if you know on which class you are getting that exception, then try to catch the Throwable object for that class only

Regards
Sudhakar
0
 
LVL 14

Expert Comment

by:sudhakar_koundinya
ID: 13504104
Ok,

one question,

Do that String array contains constant values or resultant values that are executed from the code??

try to use Hashtable in such casess

as an example
Hashtable ht=new Hashtable();
Vector vect =new Vector();
vect.add("Tiger");
vect.add("Lion");
vect.add("Monkey");
ht.put("animals",vect);

vect.add("Banana");
vect.add("Orange");
vect.add("Water Melon");
ht.put("fruits",vect);

if you do so, you can place only the objects of required size.

And note that JVM has limitations over using heap memory. So you need to concentrate further on code optimization only

Regards
Sudhakar
0
 
LVL 2

Author Comment

by:amacfarl
ID: 13504111
unfortunately I do not know that either.

basically when I execute the code in JBulder the error message java.lang.OutOfMemoryError appears in the execution pane. No other information is provided at all.

When I execute the application outside JBuilder, then I get no message.  The application just stops after 1.5 hours execution (approx).

0
 
LVL 14

Expert Comment

by:sudhakar_koundinya
ID: 13504121
if it is database related project, try to use paging concept for database communication. Don't fetch all the records at a time. On fly try to get only limited amt of data by specifying batch size. if new one is requested, clea the old list and get the new batch

Regards
Sudhakar
0
 
LVL 5

Expert Comment

by:ashok3sep
ID: 13504753
Why dont you release the String Array after using them .......

if you do so you can get rid of these erros.


or else explicitly call System.gc();

to call the Garbage Collector to release the Memory and i think it could be useful for your solution......


regards,

Freedom
0
 
LVL 1

Accepted Solution

by:
boazbl1 earned 2000 total points
ID: 13506129
The try/catch mechanism would not work, since the OutOfMemory can occur on any thread, not only the thread you created.
The solution is

      private static byte [] memoryHolder = new byte[100000];
      private static boolean outOfMemoryNotified = false;
    private static class TG extends ThreadGroup {
        public TG() {
            super("Main Thread Group");
        }
       
        public void uncaughtException(Thread t, Throwable e) {
                  if (e instanceof OutOfMemoryError) {
                        synchronized(this){
                              if (!outOfMemoryNotified) {
                                    memoryHolder = null;
                                    Runtime.getRuntime().gc();
                                    outOfMemoryNotified = true;
                                    System.err.println("Insufficient memory. This application will be closed.");
                                    System.err.println("Thread: " + t);
                                    JOptionPane.showMessageDialog(null, "Insufficient memory. This application will be closed.", "Error", JOptionPane.ERROR_MESSAGE);
                                    System.exit(1);
                              }
                        }
                  }
              super.uncaughtException(t, e);
        }
    }
   
    private static class MainThread extends Thread{
          private String[] args;
          public MainThread(String[] args) {
                super(new TG(), "Main Thread");
                this.args = args;
          }
          
          public void run() {
            // use the code from the original                     public static main(String[] args)
          }
    }

    public static void main(String[] args){
          Thread thread = new MainThread(args);
          thread.start();
      }
0
 
LVL 2

Author Comment

by:amacfarl
ID: 13532570
THANKS!!!
0

Featured Post

Get real performance insights from real users

Key features:
- Total Pages Views and Load times
- Top Pages Viewed and Load Times
- Real Time Site Page Build Performance
- Users’ Browser and Platform Performance
- Geographic User Breakdown
- And more

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

After being asked a question last year, I went into one of my moods where I did some research and code just for the fun and learning of it all.  Subsequently, from this journey, I put together this article on "Range Searching Using Visual Basic.NET …
Are you developing a Java application and want to create Excel Spreadsheets? You have come to the right place, this article will describe how you can create Excel Spreadsheets from a Java Application. For the purposes of this article, I will be u…
Viewers will learn about arithmetic and Boolean expressions in Java and the logical operators used to create Boolean expressions. We will cover the symbols used for arithmetic expressions and define each logical operator and how to use them in Boole…
The viewer will learn how to implement Singleton Design Pattern in Java.
Suggested Courses
Course of the Month12 days, 10 hours left to enroll

777 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question