Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (511)
Games in Android Showcase (119)
games submitted by our members
Games in WIP (577)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  How do you catch and handle OutOfMemoryError?  (Read 3631 times)
0 Members and 1 Guest are viewing this topic.
Offline blahblahblahh

JGO Coder


Medals: 1


http://t-machine.org


« Posted 2005-06-12 15:19:37 »

I've got some OOME's that are being thrown by Sun libraries apparently with no stacktrace. Is this:

a. a bug, and a bloody difficult one to workaround
b. a "clever" feature designed not to allocate any memory (by building a stacktrace) when there's none left
c. something else?

I can narrow down the OOME to a few lines of code, where all NIO is surrounded in an OOME handler that is known to work (usually - maybe this is a bug in NIO and sometimes they "lose" the stack trace"?) and the other stuff is adding a few items to a list. HOWEVER, immediately after the items are added to the list, lots of other allocations take place, and these all went through *fine*.

And...how on earth do you debug an app that throws generic unchecked exceptions with no stack trace?

NB: the root cause of this appears to be that other evil bug in NIO I mentioned the other week, which causes certain slightly dodgy web-browsers (notably Opera) to spam the server with requests for the same file as fast as they can until it crashes.

malloc will be first against the wall when the revolution comes...
Offline Riven
« League of Dukes »

JGO Overlord


Medals: 816
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #1 - Posted 2005-06-12 16:39:08 »

I have no solution here, but to my understanding a java.lang.Error should never be handled or caught. Errors are supposed to be fatal and threated that way.

I know this won't help you, but I thought it should be noted.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline blahblahblahh

JGO Coder


Medals: 1


http://t-machine.org


« Reply #2 - Posted 2005-06-12 17:16:24 »

I have no solution here, but to my understanding a java.lang.Error should never be handled or caught. Errors are supposed to be fatal and threated that way.

You mean you write your apps with the deliberate aim to "just crash"?

Errors are NOT supposed to be ignored. They are runtime-exceptions that you are not forced to programmatically handle at any particular point since otherwise you would have to handle them at EVERY point.

Personally, I make heavy use of custom ThreadGroup's and other catch-alls at relevant points within my apps.

malloc will be first against the wall when the revolution comes...
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Matzon

JGO Knight


Medals: 19
Projects: 1


I'm gonna wring your pants!


« Reply #3 - Posted 2005-06-12 18:21:55 »

Errors are NOT supposed to be ignored.
"An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch."

They are runtime-exceptions that you are not forced to programmatically handle at any particular point since otherwise you would have to handle them at EVERY point.
Errors are NOT runtime exceptions! - by their very definition, they're not even exceptions! - they are throwables, and as such can be caught. whether or not to catch them is an entirely different thing. As stated in the error/exception documentations, Errors - and even more so, Throwables, are typically ignored for most, and especially all simple programs.

Offline blahblahblahh

JGO Coder


Medals: 1


http://t-machine.org


« Reply #4 - Posted 2005-06-12 18:41:44 »

Errors are NOT supposed to be ignored.
"An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch."

As my professor once said "if that's your definition of 'reasonable' then the pinnacle of your career is going to be third-class assistant technician working in the NHS on practical no pay for a boss who hasn't a clue what a computer actually is".

A game that crashes out just looks...crap.

A server that crashes *EVER* is not far from useless.

EDIT: so, e.g., the server carries on executing once this OOME is handled, and it logged several thousand failed HTTP requests due to successive OOME's, but that doesn't help me debug the program. By not crashing I at least - for instance - have a full and complete record of what visitors attempted ot come to the site in that time, and what resources they were requesting, and where they were referred from, etc etc. Crashing is just NOT an option.

Quote
They are runtime-exceptions that you are not forced to programmatically handle at any particular point since otherwise you would have to handle them at EVERY point.
Errors are NOT runtime exceptions!

I meant in the general sense of the word, not in the java-sense (I would have used a capital E if I'd meant that)

Quote
- by their very definition, they're not even exceptions! - they are throwables, and as such can be caught. whether or not to catch them is an entirely different thing. As stated in the error/exception documentations, Errors - and even more so, Throwables, are typically ignored for most, and especially all simple programs.

Production programs should never ignore any throwable - especially since it only takes 10 lines of code to catch every possible throwable and handle it in [whatever default way you like]. My preference is error-dialog to user indicating where the error appears to have occurred.

Decent programs have a couple of catch's for common generic errors, and provide helpful dialogs to the user, e.g.:

  oome: "Try starting the program with -mx512m, or closing some other applications before running this app"
  npe: "Check if a newer version of this app is available, or send the following error information to person@address.com [insert stacktrace]"
  beanshellexception's: "Your scripts may have been corrupted or you've been editing them yourself, in which case please check the source code near line [insert line from stacktrace]"
  ...etc

malloc will be first against the wall when the revolution comes...
Offline Riven
« League of Dukes »

JGO Overlord


Medals: 816
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #5 - Posted 2005-06-12 19:28:09 »

I have no solution here, but to my understanding a java.lang.Error should never be handled or caught. Errors are supposed to be fatal and threated that way.
Errors are NOT supposed to be ignored.

Read what I say, before you launch yet-another-flamebait Roll Eyes



blahblahblahh> They are runtime-exceptions that you ... <snip>
Matzon> Errors are NOT runtime exceptions!
blahblahblahh> I meant in the general sense of the word, not in the java-sense (I would have used a capital E if I'd meant that)

Yeah right... that's so obvious.



Errors are thrown in situations at a point where you should not try to recover. The VM might be in a unknown state. It's not that weird that there is no stacktrace in such a scenario, although it would be extremely useful to have one.

I hope you don't twist my words this time. Thank you.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline Matzon

JGO Knight


Medals: 19
Projects: 1


I'm gonna wring your pants!


« Reply #6 - Posted 2005-06-12 19:35:37 »

Quote
Production programs should never ignore any throwable - especially since it only takes 10 lines of code to catch every possible throwable and handle it in [whatever default way you like].
Right, but some errors just can't be handled gracefully, and the only thing to do is print a decent message, log it, and exit. Which in essence is basically what crashing with a stacktrace IS - just not a pretty.

Quote
A server that crashes *EVER* is not far from useless.
Right, we've both been in the real world, and we both know that servers DO crash - all farking servers in the world. The only issue at hand is how critical it is. For 95% (guess) of all servers out there, its an annoyance, but not mission critical. The thing to get a grip on is reality. You can throw a gazillion man hours into fixing an obscure bug that happens once a month, or even less - or you could just let a nagios like warning system tell you its time to reboot the box. Most choose the latter (unless you have some sort of statemanagement like a MMORPG, where you *really* want it to stay alive, then you throw a gazillion man hours after it).
Incidentally, I have more than once seen JGF throw me an exception instead of logging it nicely, and tell me to try again later Wink

Quote
Crashing is just NOT an option.
Thats just the purist view. I have seen lots of apps crash, AAA titles, several 10s of thousands programs - and yet people strangly still buy them... I remeber Unreal throwing a nice UnrealScript exception ever so often, and yet people still enjoyed the game. Should they have waited 6 more months to fix whatever bug that was ? - it's a developers dream come true, but a management nightmare.

Quote
I meant in the general sense of the word, not in the java-sense (I would have used a capital E if I'd meant that)
Right, so Exception you're talking Java, and exception you're talking in a general sense - silly me, that is obvious...........


Offline Jeff

JGO Coder




Got any cats?


« Reply #7 - Posted 2005-06-12 19:59:42 »

To actually answer the question.

You cannot catch an OOME because it is a *fatal* error.

Code has failed in a fundemental way.  The garbage collector has tried to get the memory necessary to continue and cannot.
Thsu the system is in a bad, udnefiend state.

The way you "handle" OOM is by the following:

(1) Make sure you dont leak objects--  a profielr si good for finding this,.

(2) ANy data yo uare keeping in memory for covneniecne rather thenn ecessaity, use a SoftReference to in order
to allow the VM to collect it unddr memory-critical conditions.

(3) If yo uare already doing 1 and 2 then by difinitio nyou have not allcoated enough memory for your Java stackl.  Either
restrat the app with a bigegr stack, or re-code your program to use less memory.

Those are really the only thinsg that make any sense in this case.  If yoiur program requries more then the stack has
to give then no amount of 'recovery" is going to help.

Edit  :ANd if failign "isnt an option" then giv e Java a HUGE stack, all the memory you have available.   It will slow down like heck when it strats paging to virtual but it will keep running UNTIL you hit the point where your only "recovery" is to buy more memory Smiley

But I *realy* don't recommend this.  if you are usign up too muich memory you want to know about it because in 99% of the cases  it means your code is broken.



Got a question about Java and game programming?  Just new to the Java Game Development Community?  Try my FAQ.  Its likely you'll learn something!

http://wiki.java.net/bin/view/Games/JeffFAQ
Offline blahblahblahh

JGO Coder


Medals: 1


http://t-machine.org


« Reply #8 - Posted 2005-06-12 20:13:16 »

To actually answer the question.

Thanks, but...
Quote
You cannot catch an OOME because it is a *fatal* error.

Code has failed in a fundemental way.  The garbage collector has tried to get the memory necessary to continue and cannot.
Thsu the system is in a bad, udnefiend state.

In that case, Jeff, please do me a favour AND TELL YOUR COLLEAGUES THIS Grin.

They wrote NIO to throw OOME when it first fails to allocate a Direct BB - that has absolutely no fatal effect on the JVM at all, and (of course!) the entire JVM (minus NIO) could then carry on executing for weeks.

Sigh. I don't write this stuff to please myself, guys...I know I'm bitter and twisted, but you can normally guarantee whatever problem I have isn't a trivial stupidity Sad

Quote
The way you "handle" OOM is by the following:

(1) Make sure you dont leak objects--  a profielr si good for finding this,.

(2) ANy data yo uare keeping in memory for covneniecne rather thenn ecessaity, use a SoftReference to in order
to allow the VM to collect it unddr memory-critical conditions.

(3) If yo uare already doing 1 and 2 then by difinitio nyou have not allcoated enough memory for your Java stackl.  Either
restrat the app with a bigegr stack, or re-code your program to use less memory.

Or, as in this case:

 - something somewhere is throwing an OOME when it probably shouldn't be

(I don't believe it's a JVM OOME, because (as noted!) the JVM carried on running and logging for many minutes, generating hundreds of MB of logfiles: you can't do that if you've no memory left, surely?)

And, of course:

 - you're 99% certain it's not actually out of memory

or:

 - it requires gigabytes of data to get to this crash - you don't want to be trying to manually reproduce this non-deterministic bug!

Quote
But I *realy* don't recommend this.  if you are usign up too muich memory you want to know about it because in 99% of the cases  it means your code is broken.

Yup - and in this case I suspect it's NIO that's broken. The lack of a stacktrace makes it all but impossible to tell.

I mean, what do you do? How the heck do you debug a broken throws clause in someone else's code on a non-desktop machine that exhibits after a few hours of activity?

malloc will be first against the wall when the revolution comes...
Offline blahblahblahh

JGO Coder


Medals: 1


http://t-machine.org


« Reply #9 - Posted 2005-06-12 20:21:08 »

Right, but some errors just can't be handled gracefully, and the only thing to do is print a decent message, log it, and exit. Which in essence is basically what crashing with a stacktrace IS - just not a pretty.

Sure - but the standard then (as noted) is to put up a dialog box (assuming GUI app) - especially since the console is often not visible.

"Just crashing" is not acceptable.

Quote
Quote
A server that crashes *EVER* is not far from useless.
Right, we've both been in the real world, and we both know that servers DO crash - all farking servers in the world. The only issue at hand is how critical it is.

Fair enough - in this case, this crash seems to be fairly common, occurring between 2 hours and 2 days after restart. That's intolerable.

Quote
(unless you have some sort of statemanagement like a MMORPG, where you *really* want it to stay alive, then you throw a gazillion man hours after it).

I admit I can get stuck in this mindset Grin - but not in this case Sad.

Quote
Incidentally, I have more than once seen JGF throw me an exception instead of logging it nicely, and tell me to try again later Wink

Indeed, and most of the exceptions it doesn't handle are because of a mind-blowingly stupid bug in Velocity - or because I wasted so much time trying to work around said bug that I ran out of time to deal with the others, and now they're halfway down a todo list Smiley.

I would very much like to get them each handled intelligently, and some observers will have noticed already that some now get a user-friendly message explaining a probable cause in human-readable terms (non-techy) - such as when you try to create the same user-account twice IIRC.

But...I need to fix this fatal problem first Sad.

Quote
Quote
Crashing is just NOT an option.
Thats just the purist view. I have seen lots of apps crash, AAA titles, several 10s of thousands programs - and yet people strangly still buy them

People still buy Valve games despite detesting Steam - but how many do NOT buy them? no-one knows, but straw polls suggest a significant number. So, the "people still buy" argument doesn't hold water: someone will always still buy this stuff, but you'll have also lost an unknown number of sales.

Quote
I remeber Unreal throwing a nice UnrealScript exception ever so often, and yet people still enjoyed the game.

Worse, it crashes 100% of the time if you have no virtual memory. Very bad bug, and sufficient to (eventually) stop me buying it - got fed up of having to create 300Mb of virtual memory for some stupid idiot code.

Quote
Right, so Exception you're talking Java, and exception you're talking in a general sense - silly me, that is obvious...........

I didn't claim it was *obvious* Tongue

malloc will be first against the wall when the revolution comes...
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Jeff

JGO Coder




Got any cats?


« Reply #10 - Posted 2005-06-12 20:28:28 »

Okay,

I may be confused here.  The topic said "How do you heldne an Out Of Memory Error."

Are you talking about an Out of memory ERROR,  or an Exception that says something about Out of Memory?

The former is a fatal error from the allocator.  The latter sounds like an unfrotunately named exeption.

An actual exception with no stack trace shoudl be impossible as a stack trace is made when an exception is
created.  That being said, exceptions thrown from code that goes through JNI migth have an incomplete trace...

Edit: If you CAN catch the OOM error then that sounds lieka  mis-design.  Ive never tried to do anything so
silly, but I can ask the VM guys why on earth its even possible.


Got a question about Java and game programming?  Just new to the Java Game Development Community?  Try my FAQ.  Its likely you'll learn something!

http://wiki.java.net/bin/view/Games/JeffFAQ
Offline Jeff

JGO Coder




Got any cats?


« Reply #11 - Posted 2005-06-12 20:48:06 »

Okayl from the javadoc for java.lang.error

"An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch."

So the answer is like the old joke about the guy who walks into the doctor's office and says "it hurts when I do this" and raises his arm.  The doctor says "well don't do that."

Don't do that.  Its a fatal error, let it fail.

I have no idea why they even defined a catchable for this but Ill ask the VM  guys next chance I get.

Got a question about Java and game programming?  Just new to the Java Game Development Community?  Try my FAQ.  Its likely you'll learn something!

http://wiki.java.net/bin/view/Games/JeffFAQ
Offline princec

JGO Kernel


Medals: 404
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #12 - Posted 2005-06-12 22:32:36 »

I'm afraid that for once I agree 100% with Blah^3. The JVM fails spectacularly badly when it gets an OOM, and this is absolutely no help at all when trying to recover from the situation. C programs have been able to recover from the situation since year dot (malloc returned -1? ok, so say something about it)

In the case of writing a mission critical server application when you get an OOM error what you want is this to happen:

1. The JVM actually expands its heap just a tiny bit more than it's actually allowed, so the JVM can execute some emergency code and allocate a little more. In fact there should be a special setting that says "and here's how much emergency heap a thread can allocate when it runs out of memory".

2. The stack trace is actually filled in, so you can actually find the bleedin error in the first place. Right now the whole exception is useless, it may as well simply crash the JVM.

3. You catch the OOM and take corrective action. Example: server responds to new client requests with a canned response ("Sorry, busy, come back later.")

And that's all there is to it. Why doesn't it do any of this now? How has anyone managed to write a decent mission critical server in Java if it can't cope gracefully with being asked to remember more stuff than it's been allowed?

Cas Smiley

Offline blahblahblahh

JGO Coder


Medals: 1


http://t-machine.org


« Reply #13 - Posted 2005-06-12 22:35:38 »

Okay,

I may be confused here.  The topic said "How do you heldne an Out Of Memory Error."

Are you talking about an Out of memory ERROR,  or an Exception that says something about Out of Memory?

The former is a fatal error from the allocator.  The latter sounds like an unfrotunately named exeption.

Just repeating what the JVM told me! Smiley If that's woefully wrong, apologies, but it's what it's saying Sad.

Don't you normally get OOME when you run out of native direct BB's?

Quote
An actual exception with no stack trace shoudl be impossible as a stack trace is made when an exception is
created.  That being said, exceptions thrown from code that goes through JNI migth have an incomplete trace...

I thought it might conceivably be an "optimization" that an empty stack trace was deliberately being provided?

malloc will be first against the wall when the revolution comes...
Offline Jeff

JGO Coder




Got any cats?


« Reply #14 - Posted 2005-06-13 01:40:37 »

I'm afraid that for once I agree 100% with Blah^3. The JVM fails spectacularly badly when it gets an OOM, and this is absolutely no help at all when trying to recover from the situation. C programs have been able to recover from the situation since year dot (malloc returned -1? ok, so say something about it)

In the case of writing a mission critical server application when you get an OOM error what you want is this to happen:

1. The JVM actually expands its heap just a tiny bit more than it's actually allowed, so the JVM can execute some emergency code and allocate a little more. In fact there should be a special setting that says "and here's how much emergency heap a thread can allocate when it runs out of memory".
An intreesting idea, you might want to RFE it.

Quote
2. The stack trace is actually filled in, so you can actually find the bleedin error in the first place. Right now the whole exception is useless, it may as well simply crash the JVM.

Cant say as I think this is terribly useful. What generally matters in an OOM condition is not where exactly it failed, but what was holding all the memory WHEN it failed.

What might be useful, IMHO, would be a cotr-type file that onatiend the state of all references att he tiem of OOM so yo ucoudl do a post-mortem inspection.
I might RFE that one Smiley


Quote
3. You catch the OOM and take corrective action. Example: server responds to new client requests with a canned response ("Sorry, busy, come back later.")

Again the big question though is how can you continue doing much of anything if all memory is exhausted?  What sort of corrective action could you take?

The only correctvie action I can see is dropping references to non-criticla data.  but those exist, you should repalce those with SoftReferences and then you wont have the OOM to begin with.


Got a question about Java and game programming?  Just new to the Java Game Development Community?  Try my FAQ.  Its likely you'll learn something!

http://wiki.java.net/bin/view/Games/JeffFAQ
Offline blahblahblahh

JGO Coder


Medals: 1


http://t-machine.org


« Reply #15 - Posted 2005-06-13 07:39:01 »

Cant say as I think this is terribly useful. What generally matters in an OOM condition is not where exactly it failed, but what was holding all the memory WHEN it failed.

I used to think that was all that mattered, but ... seeing as Sun's libraries nowadays appear to throw OOME when there's still memory around, it has *become* critical to also know *where* the OOME was thrown.

To be honest, though, I'm suprised when I think about it that the JVM does not have the auto-catch-OOME-and-print-clever-output-info feature - I mean, this is a HUGE advantage of java over C++, that it has the ability to do such a thing, surely?

malloc will be first against the wall when the revolution comes...
Offline Jeff

JGO Coder




Got any cats?


« Reply #16 - Posted 2005-06-13 23:59:02 »

Yeah al lthe info is there, thats why you can use a profiler to lookat memory.

Im gonan have to suggest such a "core dump" to someone in the VM team.

Got a question about Java and game programming?  Just new to the Java Game Development Community?  Try my FAQ.  Its likely you'll learn something!

http://wiki.java.net/bin/view/Games/JeffFAQ
Offline princec

JGO Kernel


Medals: 404
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #17 - Posted 2005-06-14 17:43:58 »

What's needed is a "soft landing". Currently -Xmx is an absolute limit but ideally you want to be able to set an amount it can grow past that to deal with the threshold being exceeded. In other words, once an allocation goes past that limit, the exception is thrown and you had better throttle the application or it WILL come up against the absolute limit shortly and a more fatal OOME will be thrown.

There's a class of OOM caused by recursion which it's very handy to have a stack trace for as well Wink So it's not entirely useless to have a stacktrace. I think the reason it's been omitted is because they figured that most people don't do recursion much and without the "soft landing" mechanism, filling in a stacktrace could easily trigger another OOME.

Perhaps you could incorporate the "soft landing" mechanism into your RFE and make it a general RFE to improve handling of low memory situations?

Cas Smiley

Offline Matzon

JGO Knight


Medals: 19
Projects: 1


I'm gonna wring your pants!


« Reply #18 - Posted 2005-06-25 13:34:42 »

saw this in mustang:
Quote
Description: The java.lang.OutOfMemoryError can be difficult to diagnose. In b26, we delivered the changes for 4753347 so that the NetBeans Profiler works well with Mustang. This is one of the best tools for doing memory profiling and finding memory leaks. But because memory leaks in application or library code aren't the only source of the dreaded java.lang.OutOfMemoryError, we've worked on a number of incremental improvements to improve the overall diagnosability of this error. For example, you should now see a stack trace when an OutOfMemoryError is thrown when the heap is full. Next, we have updated the experimental jmap utility so that it can generate a heap dump or print information about objects pending finalization. We've also added a VM diagnostic option that will allow administrators to configure data collection scripts to run when the heap is full. Native heap exhaustion has been improved too so that when it is detected in the Java HotSpot VM, a fatal error log will be generated. Finally, the garbage collection team has updated the VM so that a long-lived Java Native Interface (JNI) critical section doesn't cause other threads to throw an OutOfMemoryError because garbage collection is blocked.

Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Longarmx (52 views)
2014-10-17 03:59:02

Norakomi (42 views)
2014-10-16 15:22:06

Norakomi (32 views)
2014-10-16 15:20:20

lcass (37 views)
2014-10-15 16:18:58

TehJavaDev (68 views)
2014-10-14 00:39:48

TehJavaDev (66 views)
2014-10-14 00:35:47

TehJavaDev (58 views)
2014-10-14 00:32:37

BurntPizza (73 views)
2014-10-11 23:24:42

BurntPizza (45 views)
2014-10-11 23:10:45

BurntPizza (85 views)
2014-10-11 22:30:10
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!