I am a c++ programmer , I know little bit about java. I know that java programmers 开发者_开发知识库do not have to work with memory directly like C++. I also know that most crashes in C++ appliations are due to memory corruptions.
So can an application written in Java crash due to a memory related issue?
Thanks
Contrary to some other answers I’ll claim that Java programs will crash as often, or possibly even more often than C++ programs.
By “crash” most people understand that a program encounters an error that isn’t properly handled, causing the application to terminate. Well, this of course happens and has got nothing to do with the way Java treats memory.
This is a good thing. What makes C++ so dangerous, and Java comparatively safe, is the precisely the fact that Java will crash in cases where C++ will happily continue running, albeit doing very wrong and potentially dangerous things (such as writing to uninitialized memory, overflowing buffers, …). Java’s crashing (e.g. throwing exceptions) prevents worse damage. C++ applications, on the other hand (due to the failure to terminate on errors), may do damage to external data or the system. Or they may just deliver a wrong (but seemingly plausible) result.
It’s against these dangers that Java guards, not against crashes per se.
java can crash.
The cause can be..
OutOfMemoryError
StackoverFlowError
OutOfMemoryError: PermGen space.
OutOfMemoryError Thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector.
StackoverFlowError StackOverflowException is thrown for execution stack overflow errors, typically in case of a very deep or unbounded recursion.
OutOfMemoryError: PermGen space The detail message PermGen space indicates that the permanent generation is full. The permanent generation is the area of the heap where class and method objects are stored. If an application loads a very large number of classes, then the size of the permanent generation might need to be increased using the -XX:MaxPermSize option.
The question was about memory problems that can cause a crash.
Other issues that can cause a crash, but can be caught by the program and recovered from posibilty are any runtimeExceptions. i.e.
ArithmeticException, ArrayStoreException, BufferOverflowException, BufferUnderflowException, CannotRedoException, CannotUndoException, ClassCastException, CMMException, ConcurrentModificationException, DOMException, EmptyStackException, IllegalArgumentException, IllegalMonitorStateException, IllegalPathStateException, IllegalStateException, ImagingOpException, IndexOutOfBoundsException, MissingResourceException, NegativeArraySizeException, NoSuchElementException, NullPointerException, ProfileDataException, ProviderException, RasterFormatException, SecurityException, SystemException, UndeclaredThrowableException, UnmodifiableSetException, UnsupportedOperationException
I wont go into these here. but have a look at... link text
yes it can :)
public void test() {
test();
}
this will crash with a StackoverFlowError
. there are a few others too - eg running out of memory will cause a crash (OutOfMemoryError
) too.
Memory corruptions in C++ don't just happen. They're caused by software errors, like writing past the end of an array. Doing that will lead to a crash in Java as well. (No language will take source code that contains an error and produce a program that does what you intended originally.) The difference is that in C++ you get "undefined behavior", i.e. the program might crash somewhere else. The Java program will crash the moment you try to write past the end of the array, which makes it much easier to find the bug.
Java programs crash all the time. The most common causes I come across are memory exhaustion and unhandled exceptions.
Of course they do crash :)
In addition to all the fine, answers, there's also the plain and simple JVM crash. For example, here's a question I asked concerning a case of a broken JVM which I can reliably crash using a particular data set (and it's not my fault: this "should not" happen... But it does ;)
I've seen server-side JVM crashes under some weird circumstances (Tomcat+Hibernate+Sun VM issue, back in the days, which were fixed, back in the days, by changing either Tomcat or the Sun VM).
I've seen JVM on the desktop side crashing when they should not (shipping commercial Java software to lots of desktop machine tend to rise the probability of you witnessing such a thing).
And the best I've seen is a JVM plain broken that I can reliably crash at work on several machines and, no, the machines ain't all having issues, they are rock-stable-solid workstations (since that post, I've tried on several machines and I can reproduce it):
Java VM: reproducable SIGSEGV on both 1.6.0_17 and 1.6.0_18, how to report?
(note that there a lot of other JVM that are fine on the same machines, with the same software/dataset).
The first thing I do when witnessing a JVM crash is change one of the software component: typically upgrading the JVM to the latest version.
So an application written in Java will never crash due to memory relate issue.
OutOfMemoryError
is certainly a memory related issue. Furthermore, you can get a "real" crash (segfault) when a bug in the JVM is encountered (which is typically written in C or C++), or when there is a hardware problem (such as bad RAM). Possibly also when you run invalid bytecode on a JVM that does not validate it (such as JVMs for embedded systems).
But normally, yes, Java programs don't segfault.
No. Java Applications can crash due to memory issues. While Java does have built-in memory management, it's by no means perfect. It's just that a lot of the hard work is done for you.
As mentioned in some of the other answers, Java does have a fairly particular memory allocation system which does involve quite a bit of manual management and it's actually quite easy to exhaust this allocation if you're not careful and don't have it set up correctly for your application.
(See the -Xmx and -Xms parameters to Java)
While it's unlikely the JVM itself will crash it's perfectly possible for your program to crash through memory related issues, e.g from memory leaks via objects that never go out of scope.
(edit: the JVM is a highly optimised platform, and although bugs are very rare, they still crop up occasionally, plus of course, as others have mentioned here, if you have hardware issues like corruped I/O or RAM, the JVM can and will die)
This program will throw OutOfMemoryException
and crash.
void crash(List list) {
while (true) {
list.add(new Object());
}
}
A serious crash looks like that:
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00000000, pid=3387, tid=166603048020
#
# JRE version: 6.0_14-b08
# Java VM: Java HotSpot(TM) Server VM (14.0-b16 mixed mode linux-x86 )
# Problematic frame:
# C 0x00000000
#
# An error report file with more information is saved as:
# .....hs_err_pid3387.log
It's not the java programm that causes this, it's the code of the vm itself. It's very rare since a few years.
If you want to test what happens if the JVM really crashes, try this function (I use it to test my crash handlers :). Works not in secure environments, or on non Sun JDKs.
/**
* Crashes the JVM, by copying 1 byte from address 1 to address 1. If this did
* not crash the machine already, we copy a byte from -1 to -1 :). Never call
* this except for debugging problems related to handling system crashes.
*/
public static void crash() {
Unsafe unsafe;
try {
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
unsafe = (Unsafe)field.get(null);
} catch (Exception ex) {
throw new RuntimeException("Can't get Unsafe instance to crash app.", ex);
}
log.fatal("Here we are and say good bye, the app ist now about to die...");
// Crash now!
unsafe.copyMemory(1,1,1);
// Still alive? Than the following line will help... Crash now!
unsafe.copyMemory(-1,-1,1);
}
精彩评论