Busting "java.lang.outofmemory"

R

Rajesh.Rapaka

Hi,
I am working on a project in which when i run out of memory, I get a
"Java.lang.outofmemory" exception. But I am not able to catch this !
i.e is every function has a try catch statement. But I am not able to
get hold of this exception.

Well u might be wondering what i wud like to do after catching it....
well I'd like to tell the user that his memory is over !!

Am I not able to catch it? or doesnt java has a way to catch this
exception?

plz help,
regards,
Rajesh Rapaka.
 
D

Daniel Dyer

Hi,
I am working on a project in which when i run out of memory, I get a
"Java.lang.outofmemory" exception. But I am not able to catch this !
i.e is every function has a try catch statement. But I am not able to
get hold of this exception.

Well u might be wondering what i wud like to do after catching it....
well I'd like to tell the user that his memory is over !!

Am I not able to catch it? or doesnt java has a way to catch this
exception?

You don't have to catch it for every method call, just for every thread on
which it could occur since it will propagate up the call stack. If you
are using Java 5 this is made easy by the new
Thread.setUncaughtExceptionHandler method. If not, you would need to put
a try...catch around the code in your main method and the code in the run
methods of any threads you spawn.

But you will have to be careful what you do when you catch it since you
won't have much/any memory to work with, so it might not work reliably.

Dan.
 
A

Andrew Thompson

I am working on a project in which when i run out of memory, I get a
"Java.lang.outofmemory"

No such error!
..exception. ...

No you don't. What you are getting is an *error*,
not an exception. Assuming you mean..
<http://java.sun.com/j2se/1.5.0/docs/api/java/lang/OutOfMemoryError.html>

Please copy/paste errors, rather than typing 'something like'
what it says. That wastes your time and our bandwidth.

See below..
..But I am not able to catch this !
i.e is every function has a try catch statement. But I am not able to
get hold of this exception.

Well u might be wondering what i wud like to do after catching it....
well I'd like to tell the user that his memory is over !!

Am I not able to catch it?

Sure you are..

Are you catching Exceptions[1], ..or Errors[2]?

(note that while both are Throwable[3],
// do dangerous stuff
...
} catch(Exception e) {

....will not catch classes under the Error hierarchy.)

[1] <http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Exception.html>
[2] <http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Error.html>
[3] <http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Throwable.html>
 
M

Martin Jost

Daniel Dyer said:
You don't have to catch it for every method call, just for every thread on
which it could occur since it will propagate up the call stack.

I'm fighting myself with this problem right now.
So here are my findings/observations: (In no particular order)
1.
You also need to be aware of your AWT/Swing threads.
You need to catch the error in each of them (besides the threads you started explicitly)
One point would be the ActionListener kicking off your action.

2.
(And probably most important) OutOfMemory is an "Error" not an Exception.
So if you catch Exceptions, you simply will miss the Errors.
So you have to catch the specific Error, all Errors or maybe even Throwable.
(But then you get all of them...)

3.
If you have no memory left, it seems the handling may well trigger at once the next OutOfMemory.
So you need a trick like that: (Borrowed from an older posting I found with google)

private static byte[] emergencyMem = new byte[8192];
public .... main(String[] a) {
try {
runApplication();
} catch (OutOfMemoryError e) {
emergencyMem = null;
// ...Rest of handling
}
}

HTH

Martin
 
E

E.Otter

I'm of the opinion that something like an "OutOfMemoryError" and just about
any other thing that ends with "Error" should not be caught. Its not
really a bug or problem in your code its a problem with the environment the
program is running in. Let the user see the problem. Your code needs to do
something and the user has a PC with either not enough memory or just too
much stuff currently running. Your code can't fix it. The user needs the
smack upside the head to get a better system or shut some junk down.
 
A

Andrew Thompson

I'm of the opinion that something like an "OutOfMemoryError" and just about
any other thing that ends with "Error" should not be caught.

As a general rule - that is idiotic.

Window.setAlwaysOnTop() is a method introduced in 1.5.
If you try it in a pre 1.5 VM you will get a 'NoSuchMethodError',
but that is no reason to throw an error up before the end user.
The programmer can simply start a thresad that keeps bringing the
desired window to front. Not as neat and elegant as 'AlwaysOnTop',
but still entirely workable.

OOME's can be handled in a better manner by the programmer
as well.
..Its not
really a bug or problem in your code its a problem with the environment the
program is running in.

Like program designed to load up to 50 images is asked to
load 327? Yes, it might be a problem with the environment,
or how the user is using/abusing the program ..but simply
dumping an error to stderr and exiting is most often neither
necessary nor optimal.
Let the user see the problem.

Tell 'em nothing, if you don't have to. It only confuses them.
 
I

iamfractal

E.Otter said:
I'm of the opinion that something like an "OutOfMemoryError" and just about
any other thing that ends with "Error" should not be caught. Its not
really a bug or problem in your code its a problem with the environment the
program is running in. Let the user see the problem. Your code needs to do
something and the user has a PC with either not enough memory or just too
much stuff currently running. Your code can't fix it. The user needs the
smack upside the head to get a better system or shut some junk down.

FWIW, I'm not of that opinion.

I recently wrote a GUI for an application: this application reads and
analyses loads of files. If the user tries to analyse too large a
system, then the application will run out of memory.

The problem is that when this OutOfMemoryError is thrown by the
application, if it's not caught, then the GUI will just hang. It won't
report the Error automatically. Thus the user waits for a while,
guesses something's gone horribly wrong, and rips it all down.

It's much better to throw up a warning dialog, telling him that the
universe is finished and he might as well give up.

Yes, I know: you cannot guarantee that there will be enough memory to
throw up the dialog, but I tried, nonetheless, and testing has shown
that the system will throw up the dialog 60% of the time. Yes, for the
other 40%, the user is just waiting for the bus that will never come;
but 60% is better than nothing.

Also, I've noticed that, even when there's no memory to throw up a
dialog, the JVM can always (apparently) do a System.out.println(); so I
do this, too. Unfortunately, most users will start the application by
double-clicking a jar file, in which case the println() sends the
message into deep space somewhere; but again: a little effort can *try*
to allieviate the user's frustration.

..ed
 
A

Andrew Thompson

Yes, I know: you cannot guarantee that there will be enough memory to
throw up the dialog, but I tried, nonetheless, and testing has shown
that the system will throw up the dialog 60% of the time. Yes, for the
other 40%, the user is just waiting for the bus that will never come;
but 60% is better than nothing.

60% of the time?! When I was fighting memory leaks in some
image software - I found I could get a dialog every time so
long as I'd prepared and packed it first (ready - just in case).

OTOH, I also like the idea mentioned by Martin (# 3).
<http://groups-beta.google.com/group/comp.lang.java.programmer/msg/01e160bb68b85329>
Instant emergency memory!
 
I

iamfractal

Andrew said:
60% of the time?! When I was fighting memory leaks in some
image software - I found I could get a dialog every time so
long as I'd prepared and packed it first (ready - just in case).

OTOH, I also like the idea mentioned by Martin (# 3).
<http://groups-beta.google.com/group/comp.lang.java.programmer/msg/01e160bb68b85329>
Instant emergency memory!

Hi, Andrew,

Thanks for the link; I've toyed with this technique (admittedly to no
great extent) and couldn't quite get it to work. This thought was
floating in my head that probably sabotaged my attempts: surely just
setting the variable to null won't force the garbage collector to
immedately free the memory before the next line is executed? Surely
setting the variable to null just identifies it for collection
*whenever* the garbage collector decides to get off his sofa and do
some work?

I will, however, put more effort into pre-manufacturing a JDialog,
though; I had no idea that this sort of problem could be handled with
100% satisfaction.

Ta, chuck,

..ed
 
A

Andrew Thompson

Andrew Thompson wrote: ... ...
I will, however, put more effort into pre-manufacturing a JDialog,
though; I had no idea that this sort of problem could be handled with
100% satisfaction.

100% satisfation guaranteed - or your money back!

But, more seriously.. If you ever see that fail, I
would be interested in hearing about it.
 
M

Martin Jost

Ok, just to get the credits right - I've borrowed the code from a posting of Stefan Matthias Aust in a German Java newsgroup.
Surely
setting the variable to null just identifies it for collection
*whenever* the garbage collector decides to get off his sofa and do
some work?

This was also discussed in the German thread (http://groups-beta.google.com/group/de.comp.lang.java/browse_thread/thread/a9d918a222935b39)
The gc should get off of its sofa really fast, because there is work to do. (In fact you just got an OOME)
There was also discussed, that another thread might use the memory, before the current thread can use it.
My own tests show, that you might need more memory, depending on what you plan to do.

Martin
 
A

Andrew Thompson

.
(reserving bytes in case of OOME)
My own tests show, that you might need more memory,
depending on what you plan to do.

Thanks for the clarification and links, Martin.

I have been meaning to try that technique.
Maybe I'll get around to it someday..
 
R

Rajesh.Rapaka

Hi all,
Thanks for the replies. Seems like there is no way using which we can
free memory manually. all we can do is NULL the variables and wait for
the VM to perform the GC.

Why are we forced to WAIT?? is there a bypass or secret passage to
activate the Garbage Collector function from the JVM ??something like
piercing into the JVM and activating the GC funtion.

Well if there is no way that i can free my used memory immediately (
like as in C++, i suppose) there is no point in using the java
technology for softwares, specially where there is huge memory
management requirement. because we already have delays from the
program, then the delays from hardware, then the delays from OS and
added to this, we have delays from JAVA itself ???

Well my complaint is not just the delay. But this delay is provocating
the crash of the system. Because when I use a mountain of memory, I
force it to get GC'd. But since the gc doesnt want to do it *now* the
mountain of NULL'ed variables is not ready to be used. and when
immediately, with i need another mountain, this will give an
OutOfMemoryError. But if the GC performs its job, I will not loose my
job !! :)

plz do tell me if there another way by which we can peep into the JVM
and activate the GC funtion. or somehow perform the GC rather than
praying for GOD!!!
regards,
Rajesh Rapaka.
 
A

Andrew Thompson

Thanks for the replies. Seems like there is no way using which we can
free memory manually. all we can do is NULL the variables and wait for
the VM to perform the GC.

What happened when you did that?
 
J

John Currier

Thanks for the replies. Seems like there is no way using which we can
free memory manually. all we can do is NULL the variables and wait for
the VM to perform the GC.

If you null the variables the GC will be able to do its job when you
"need another mountain."

John
http://schemaspy.sourceforge.net

p.s. it's null, not NULL. This isn't a macro-based language.
 
M

Martin Jost

Why are we forced to WAIT?? is there a bypass or secret passage to
activate the Garbage Collector function from the JVM ??something like
piercing into the JVM and activating the GC funtion.

You could try to use System.gc():
System.gc()
------------------
public static void gc()Runs the garbage collector.
Calling the gc method suggests that the Java Virtual Machine expend effort toward recycling unused objects in order to make the memory they currently occupy available for quick reuse. When control returns from the method call, the Java Virtual Machine has made a best effort to reclaim space from all discarded objects.

The call System.gc() is effectively equivalent to the call:

Runtime.getRuntime().gc()

See Also:
Runtime.gc()
------------------
BUT... the thread I already quoted strongly suggested, that the gc works best, when left alone.

HTH

Martin
 
I

iamfractal

Hi, Rajesh,

You wrote, "Because when I use a mountain of memory, I
force it to get GC'd."

Remember, the garbage collector does just that: it collects garbage,
i.e., memory that's reserved for use, but whose users no longer have
interest in it. If you're using a mountain of memory, it may be that
you just don't have enough RAM.

If, for example, you've 1mb of RAM and need to loaded a 2mb jpeg into
memory, then no amounf of garbage collection, and no other language's
memory management algorithms, will help you.

..ed
 
M

Martin Jost

If, for example, you've 1mb of RAM and need to loaded a 2mb jpeg into
memory, then no amounf of garbage collection, and no other language's
memory management algorithms, will help you.

Two notes...

1.
You are aware, that the jre might/does _not_ use all memory on your machine by default ?
E.g. my version (1.4.2_06-b3) has options for that:
-Xms<size> set initial Java heap size
-Xmx<size> set maximum Java heap size
-Xss<size> set java thread stack size

This comes with a note: "The -X options are non-standard and subject to change without notice."
You might need to bump these to use the available memory.
(Does someone know, how to get hold of the defaults for those ?)

2.
What version of the JRE are you using ?
It seems that older versions had their share of problems concerning GC.

HTH

Martin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top