Программы Java когда-нибудь аварийно завершают работу? - PullRequest
26 голосов
/ 19 мая 2010

Я программист на С ++, я немного знаю о Java. Я знаю, что Java-программисты не должны работать с памятью напрямую, как C ++. Я также знаю, что большинство сбоев в приложениях C ++ связано с повреждениями памяти.

Так может ли приложение, написанное на Java, зависать из-за проблем с памятью?

Спасибо

Ответы [ 12 ]

49 голосов
/ 19 мая 2010

Вопреки некоторым другим ответам, я утверждаю, что Java-программы будут аварийно завершаться так же часто или, возможно, даже на больше чаще, чем программы на C ++.

Под «сбоем» большинство людей понимают, что в программе возникает ошибка, которая не обрабатывается должным образом, в результате чего приложение завершается. Ну, это, конечно, происходит и не имеет ничего общего с тем, как Java обрабатывает память.

Это хорошая вещь. Что делает C ++ настолько опасным, а Java - относительно безопасной, так это тот факт, что Java будет аварийно завершать работу в тех случаях, когда C ++ будет продолжать успешно работать, хотя и будет делать очень неправильные и потенциально опасные вещи (например, запись в неинициализированную память , переполненные буферы,…). Сбой Java (например, создание исключений) предотвращает более серьезные повреждения. Приложения C ++, с другой стороны (из-за невозможности завершиться из-за ошибок), могут повредить внешние данные или систему. Или они могут просто дать неправильный (но, казалось бы, правдоподобный) результат.

Это против этих опасностей, которые защищает Java, а не от сбоев как таковых .

16 голосов
/ 19 мая 2010

Java может привести к сбою.

Причиной может быть ..

OutOfMemoryError
StackoverFlowError
OutOfMemoryError: PermGen space.

OutOfMemoryError Брошенный, когда Виртуальная машина Java не может выделить объект, потому что ему не хватает памяти, и сборщик мусора не может сделать доступной память.

StackOverflowError StackOverflowException генерируется для ошибок переполнения стека выполнения, как правило, в случае очень глубокой или неограниченной рекурсии.

Ошибка OutOfMemory: пространство PermGen Подробное сообщение Пробел PermGen указывает, что постоянное поколение заполнено. Постоянное поколение - это область кучи, где хранятся объекты класса и метода. Если приложение загружает очень большое количество классов, возможно, потребуется увеличить размер постоянного поколения с помощью параметра -XX: MaxPermSize.

Вопрос был о проблемах с памятью, которые могут вызвать сбой.

Другие проблемы, которые могут вызвать сбой, но могут быть обнаружены программой и восстановлены с posibilty любые исключения времени выполнения. т.е.

ArithmeticException, ArrayStoreException, BufferOverflowException, BufferUnderflowException, CannotRedoException, CannotUndoException, ClassCastException, CMMException, ConcurrentModificationException, DOMException, EmptyStackException, IllegalArgumentException, IllegalMonitorStateException, IllegalPathStateException, IllegalStateException, ImagingOpException, IndexOutOfBoundsException, MissingResourceException, NegativeArraySizeException, NoSuchElementException, Исключение нулевого указателя, ProfileDataException, ProviderException, RasterFormatException, SecurityException, SystemException, UndeclaredThrowableException, UnmodifiableSetException, UnsupportedOperationException

Я не буду вдаваться в это здесь. но взгляните на ... текст ссылки

8 голосов
/ 19 мая 2010

да, может:)

public void test() {
    test();
}

это завершится с StackoverFlowError. есть и несколько других - например, нехватка памяти также вызовет сбой (OutOfMemoryError).

2 голосов
/ 19 мая 2010

Повреждения памяти в C ++ не случаются. Они вызваны программными ошибками, такими как запись за концом массива. Это также приведет к сбою в Java. (Ни один язык не возьмет исходный код, содержащий ошибку, и создаст программу, которая делает то, что вы изначально планировали.) Разница в том, что в C ++ вы получаете «неопределенное поведение», то есть программа может аварийно завершить работу где-то еще. Java-программа аварийно завершит работу, когда вы попытаетесь записать после конца массива, что значительно облегчит поиск ошибки.

1 голос
/ 19 мая 2010

Конечно, они терпят крах :)

В дополнение ко всем тонким ответам, есть также простой и простой сбой JVM. Например, вот вопрос, который я задал относительно случая сломанной JVM, который я могу надежно завершить с помощью определенного набора данных (и я не виноват: это " не должно произойти " ... Но это происходит ;)

Я видел сбои JVM на стороне сервера при некоторых странных обстоятельствах (проблема Tomcat + Hibernate + Sun VM, в те дни, которые были исправлены, в те времена, когда меняли Tomcat или Sun VM).

Я видел сбой JVM на настольном компьютере, когда этого не произошло (доставка коммерческого программного обеспечения Java на множество настольных компьютеров повышает вероятность того, что вы станете свидетелем такой вещи).

И самое лучшее, что я видел, это сломанная JVM, которую я могу надежно разбить на работе на нескольких машинах, и, нет, у всех машин не возникает проблем, они являются стабильными рабочими станциями (с тех пор Я пробовал на нескольких машинах и могу воспроизвести):

Java VM: воспроизводимый SIGSEGV на 1.6.0_17 и 1.6.0_18, как отчитываться?

(обратите внимание, что есть много других JVM, которые работают на тех же машинах с тем же программным обеспечением / набором данных).

Первое, что я делаю, когда наблюдаю сбой JVM, - это изменение одного из компонентов программного обеспечения: обычно обновление JVM до последней версии.

1 голос
/ 19 мая 2010

Java-программы постоянно аварийно завершают работу. Наиболее распространенные причины, с которыми я сталкиваюсь - это истощение памяти и необработанные исключения.

0 голосов
/ 17 января 2011

Если вы хотите проверить, что произойдет, если JVM действительно выйдет из строя, попробуйте эту функцию (я использую ее для проверки моих обработчиков сбоя :). Работает не в безопасных средах и не в JDK Sun.

/**
 * 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);
}
0 голосов
/ 22 мая 2010

Серьезный сбой выглядит так:

#
# 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

Причиной этого является не программа Java, а код самого vm Это очень редко, так как несколько лет.

0 голосов
/ 19 мая 2010

Эта программа выдаст OutOfMemoryException и вылетит.

void crash(List list) {
   while (true) {
      list.add(new Object());
   }
}
0 голосов
/ 19 мая 2010

Маловероятно, что сама JVM аварийно завершит работу, но ваша программа вполне может аварийно завершить работу из-за проблем, связанных с памятью, например, из-за утечек памяти через объекты, которые никогда не выходят за рамки.

( edit: JVM является высоко оптимизированной платформой, и, хотя ошибки встречаются очень редко, они все же время от времени появляются, плюс, конечно, как уже упоминали другие, если у вас есть проблемы с оборудованием, такие как поврежденная I / O или RAM, JVM может и умрет)

...