So today while learning Java, I finally encountered this particular error. It seems that this error is pretty prevalent and trying to recover from it has garnered mixed reactions. Some think it is useful in certain scenarios so its a good 'good to know', some have used it in their projects, while others vehemently oppose the idea of catching this error and then a lot of others are just as confused as me.
Edit: Oh btw, this is the error that I have encountered. I wish to catch these errors and decrease the value of incrementor by 1/10th next time until another error is found
(and so on... until I find the upper bound)
Since I'm taking my baby steps in Java and cannot find anything much specific on this topic, I'd like to ask your help on this particular example:
public class SpeedDemoClass {
static int iterations=0;
static int incrementor=10000000;
public static void main(String[] args) {
while(incrementor>1){
try{
iterations=iterations+incrementor;
iterator(iterations);
}
catch(Exception e){
System.out.println("So this is the limiting error: "+e);
iterations=iterations-incrementor;
incrementor=incrementor/10;
iterations=iterations+incrementor;
}
}
System.out.println("The upper limit of iterations is: "+iterations);
}
public static void iterator(int a){
long start_time= System.currentTimeMillis();
StringBuilder sbuild= new StringBuilder("JAVA");
for(int i=0;i<a;i++){
sbuild.append("JAVA");
}
System.out.println("Performing "+a+" append operations;"
+"process completed in :"
+(System.currentTimeMillis()-start_time)+"ms");
}
}
Did you try compiling it?
Ofcourse, it does not work
I am trying to do the following:
With my own manual tests, I have found out the value of this to be 92,274,686. That's the magic number. I don't know why it is so, and whether or not it is that value for my own computer only. It would be awesome if someone could post a modified code that could spit out this result.
In other words if an OOME is thrown in an application server (jboss/websphere/..) do I have to restart it? No you don't have to restart. But it is probably wise to, especially if you don't have a good / automated way of checking that the service is running correctly. The JVM will recover just fine.
lang. OutOfMemoryError exception. Usually, this error is thrown when there is insufficient space to allocate an object in the Java heap. In this case, The garbage collector cannot make space available to accommodate a new object, and the heap cannot be expanded further.
There are several ways to eliminate a heap memory issue: Increase the maximum amount of heap available to the VM using the -Xmx VM argument. Use partitioning to distribute the data over additional machines. Overflow or expire the region data to reduce the heap memory footprint of the regions.
You catch Exception
, but OutOfMemoryError
is an Error
. Note that Error
and Exception
are two different classes in Java! Both implement Throwable
, though.
The catch
clause restricts the type of Throwable classes to be caught. As Error
is not an Exception
, your code won't catch OutOfMemoryError
.
That "magic number" will change if you allocate some extra objects that use up memory, use a PC with less memory etc. or allocate memory smart. Trying to estimate memory consumption brute-force is a bad idea!
Instead, understand how Java memory allocations work, how the memory layout of a string builder is, and how to control this. Here, you should study the method ensureCapacityInternal
.
Look at the error you get - in particular the classes and line numbers.
I bet that if you replace this line:
StringBuilder sbuild= new StringBuilder("JAVA");
by
StringBuilder sbuild= new StringBuilder(500000000);
Then you get much further before seeing an OOM error. Catching this error is not a very clever way. There are some nice variants to observe memory consumption; but you really should use them only once you have understood memory organization of Java, so you don't draw wrong conclusions.
Your PC probably has 8 GB of RAM? Try using java -Xmx7500m
. You may be able to go 3x as far. Because by default, Java only uses 25% of your memory simply to allow other processes to use some memory, too. If you want Java to use all your memory, you have to tell it that this is desired.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With