Update: Per suggestions from readers, the title of this article is changed from “How to crash a JVM easily” to “How to crash a Java app easily?
If you can make it, then you should know how to break it. I think its more applicable to software systems than anything else. Being Java developers, we occasionally see JVM crashing either because we do something really silly or probably due to system’s limitation(bug, memory, threads etc.). But I was wondering, if I want to crash a JVM deliberately, what is the easiest way? In other words, with less line of code.
How “easy” is to crash a JVM? I am not talking about killing the process from Task Manager or running kill command in Unix
.
Here are some of the options I came up with. If anyone can think of more “creative” ways, feel free to share it on the comments.
1.) JVM crash due to StackOverflow.
public class JVMCrashTest {
public static void main(String[] args) {
main(args);
}
}
Exception in thread “main” java.lang.StackOverflowError
2.) This one will fail due to memory not being enough. We can use the same technique with data types other than Integer.
public class JVMCrashTest {
public static void main(String[] args) {
Integer integers[] = new Integer[Integer.MAX_VALUE];
}
}
Exception in thread “main” java.lang.OutOfMemoryError: Requested array size exceeds VM limit
3.) This technique is very similar to the second one. Again, this approach can be tried with other data structures also.
import java.util.*;
public class JVMCrashTest {
public static void main(String[] args) {
ArrayList list = new ArrayList();
for (int i = 0; i < Integer.MAX_VALUE; i++) {
list.add(new Object());
}
}
}
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
We constructively crashed the JVM, so now what?. Let's talk little bit about these approaches. Option 1 is very simple(less code) and my most favorite. It got into my thinking little more than how JVM can be crashed, possibly hinting some limitations which I never thought of before. But, I am going to save that discussion for a separate topic of its own.
Option 2 & 3 are very similar which may be fixed by adding more memory. In the meanwhile, if anyone can add more to this list, it will be great.
Note: The above code was run using JDK 1.6.0_18's JVM with the default memory settings.
I saw the “How can you crash the JVM with a few lines of code?” question a few weeks ago in an interview questionnaire. I thought about the 1st example, not the others. Good to know!
public class Dumb {
public static void main(String[] args) {
throw new StackOverflowError();
}
}
Also, you can crash Sun JVM’s garbage collector with this:
Object[] o = null;
while (true) { o = new Object[] { o }; }
Your examples only kill the running thread, not the JVM.
And your ‘tricks’ to get an Error thrown are so simple that a simple catch (Error|Throwable) will be enough to recover the JVM to fully working order.
Bit long, but a proper crash
import java.lang.reflect.Field;
import java.nio.ByteBuffer;
import sun.misc.Unsafe;
public class Crash {
public static void main(String[] args) throws Exception {
ByteBuffer bb = ByteBuffer.allocateDirect(1);
Field field = bb.getClass().getDeclaredField(“unsafe”);
field.setAccessible(true);
Unsafe unsafe = (Unsafe)field.get(null);
unsafe.copyMemory(0, 0, 1);
}
}
Variation on your method 3, this time perm gen space
import java.util.ArrayList;
public class Crash {
public static void main(String[] args) throws Exception {
ArrayList al = new ArrayList();
for ( long i = 0; i < Long.MAX_VALUE; i++ ) { al.add(Long.toBinaryString(i).intern());
}
}
}
bravo !!!
Hi Artur,
Both your approaches are pretty interesting. Obviously the first one is technically profound.
Attila,
I never thought of that before. Yes, it’s not a bad question for an interview
If you never wrote a native method nor use JNI, just do it. Chances are good that you will then see a real JVM crash rather a trivial Java exception.
Throwing an Exception, or Error to the VM is not “crashing” the VM. The VM handles this perfectly fine. This post is incredibly inaccurate.
These are not crashes. http://en.wikipedia.org/wiki/Crash_%28computing%29
You just made the JVM to “kill” your application because you didn’t allocated enough memory to perform.
A crash should kill your JVM, no exception reporting only a segmentation fault or a hs_err* report.
Try this:
public class Crash {
public static void main(String[] args) {
Object[] o = null;
while (true) {
o = new Object[] { o };
}
}
}
Hi Derrick,
Killing/crashing is a debatable term from VM run perspective. You have the right to express your view point.
Crash computing.. Interesting…
I never heard of that before.
Thanks for posting the link.
Another effective technique for crashing a jvm is to run it on linux.
I don’t agree with you that these example “crash” the JVM. The examples throw an exception, that’s the *application* crashing; not the JVM.
To really crash the JVM, you need to dereference a null pointer in C code (called via JNI from the JVM).
I don’t agree that JVM should die by generating “hs_err_*.log” to be considered a crash. Then, we probably need to rephrase the title to.. “How to crash JVM natively?”.
JVM is a system running native and non-native code. The point is.. it terminates not able to run some code. That’s all we are trying to accomplish. It really doesn’t matter whether we crash it using native or non-native code
What about performance optimizations in Java, should that be done in native code also in order to be considered “a real optimization”?
You are really misleading the terminology of what JVM crash means. JVM crash as everybody understands is when JVM is not able to handle the condition gracefully, kills all threads, and generates the core dump. Any non-native Java code should never crash the JVM (if it did it is always due to JVM bug).
Let’s take a look at your examples.
1. Modify your first example to create a another thread and notice that JVM doesn’t die but just kills the main thread. This is not considered a JVM crash but application logic issue.
public class JVMCrashTest {
public static boolean done = false;
public static void main(String[] args) {
if (!done) {
new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(1000000);
} catch (Exception e) {
//Ignore
}
}
}).start();
done = true;
}
main(args);
}
}
2. It is same for second example.
public class JVMCrashTest {
public static boolean done = false;
public static void main(String[] args) {
if (!done) {
new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(1000000);
} catch (Exception e) {
//Ignore
}
}
}).start();
done = true;
}
Integer integers[] = new Integer[Integer.MAX_VALUE];
}
}
3. And it is again same for third example.
import java.util.*;
public class JVMCrashTest {
public static boolean done = false;
public static void main(String[] args) {
if (!done) {
new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(1000000);
} catch (Exception e) {
//Ignore
}
}
}).start();
done = true;
}
ArrayList list = new ArrayList();
for (int i = 0; i < Integer.MAX_VALUE; i++) {
list.add(new Object());
}
}
}
However, it seems it is possible to *really* crash the JVM (not just kill the thread executing the code) is mentioned at this post http://stackoverflow.com/questions/65200/how-do-you-crash-a-jvm
So please be considerate to others when they try to correct your inaccurate post and I hope you update the post to rectify this.
Hi Kumar,
Thanks for taking time to express your thoughts.
I’ll try to make this simple. A system can die “gracefully” or “non-gracefully”. If the weblogic or tomcat die due to OutOfMemoryError, I call it a “crash”. Yes, it’s not JVM’s fault but, it’s still a system crash. If you want, you can perfectly handle the errors and keep going without dying.
If you read through the answers posted in the StackOverFlow link you gave, there are some folks who added similar examples like I did. So, I am not the only one who think this as crashing.
By no means, I am not trying to find a flaw in JVM or undermine it’s robustness. Here is a simple metaphor I could think of for this scenario…
A car can be crashed by a reckless driver running over a building or it can go out of whack and got crashed due to some mechanical/logistical malfunctioning like the recent Toyota’s story.
Hope it clears some confusions.
To clear these confusions, you should change the title to “How to crash a Java application”.