Как вы терпите крах JVM? - PullRequest
140 голосов
/ 15 сентября 2008

Я читал книгу о навыках программирования, в которой автор спрашивает интервьюируемого: «Как ты разбил JVM?» Я думал, что вы можете сделать это, написав бесконечный цикл for, который в конечном итоге израсходует всю память.

У кого-нибудь есть идеи?

Ответы [ 25 ]

5 голосов
/ 15 июня 2016

Не сбой, но ближе к сбоям, чем принятый ответ использования System.exit

Вы можете остановить JVM, позвонив по номеру

Runtime.getRuntime().halt( status )

Согласно документам: -

«этот метод не запускает перехватчики завершения работы и не запускает непроверенные финализаторы, если включена финализация при выходе».

5 голосов
/ 04 мая 2009

Сломанное оборудование может привести к сбою любой программы. Однажды я воспроизводил аварийное завершение работы приложения на определенной машине, в то время как на других машинах он работал точно с такой же настройкой. Оказывается, у машины был сбой ОЗУ.

5 голосов
/ 07 апреля 2014

кратчайший путь:)

public class Crash
{
    public static void main(String[] args)
    {
        main(args);
    }
}
5 голосов
/ 20 сентября 2008

на winxpsp2 с wmp10 jre6.0_7

Desktop.open (uriToAviOrMpgFile)

Это приводит к тому, что порожденная нить генерирует неперехваченный Throwable и вылетает из точки доступа

YMMV

5 голосов
/ 15 сентября 2008

Наиболее близким к одному "ответу" является System.exit(), который немедленно завершает работу JVM без надлежащей очистки. Но кроме этого, нативный код и исчерпание ресурсов являются наиболее вероятными ответами. В качестве альтернативы вы можете посмотреть на систему отслеживания ошибок Sun на предмет ошибок в вашей версии JVM, некоторые из которых допускают повторяющиеся сценарии сбоев. Мы привыкли к полурегулярным сбоям при приближении к пределу памяти 4 Гб в 32-битных версиях (сейчас мы обычно используем 64-битные).

4 голосов
/ 30 сентября 2008

Вот подробное объяснение того, что вызывает JVM к дампу ядра (т.е. сбой): http://kb.adobe.com/selfservice/viewContent.do?externalId=tn_17534

4 голосов
/ 16 сентября 2008

Если вы определяете сбой как прерывание процесса из-за необработанной ситуации (то есть отсутствия исключений или ошибок Java), то это невозможно сделать из Java (если у вас нет разрешения на использование класса sun.misc.Unsafe) , В этом весь смысл управляемого кода.

Типичные сбои в собственном коде происходят из-за разыменования указателей на неправильные области памяти (нулевой адрес или неправильное выравнивание). Другим источником могут быть недопустимые машинные инструкции (коды операций) или необработанные сигналы от вызовов библиотеки или ядра. Оба могут быть запущены, если в JVM или в системных библиотеках есть ошибки.

Например, JIT-код (сгенерированный), нативные методы или системные вызовы (графический драйвер) могут иметь проблемы, приводящие к реальным сбоям (было довольно часто случаться сбой, когда вы использовали функции ZIP, и у них не хватало памяти). В этих случаях обработчик сбоя JVM запускает и выводит состояние. Он также может генерировать файл ядра ОС (Dr. Watson в Windows и дамп ядра в * nix).

В Linux / Unix вы можете легко вызвать сбой JVM, отправив ему сигнал запущенному процессу. Примечание: вы не должны использовать SIGSEGV для этого, так как Hotspot ловит этот сигнал и повторно генерирует его как NullPointerException в большинстве мест. Так что лучше отправить SIGBUS например.

3 голосов
/ 29 апреля 2009

Если вы хотите притвориться, что вам не хватает памяти, вы можете сделать

public static void main(String[] args) {
    throw new OutOfmemoryError();
}

Я знаю несколько способов заставить JVM вывести файл ошибки, вызывая собственные методы (встроенные), но, вероятно, лучше не знать, как это сделать. ;)

3 голосов
/ 29 апреля 2009

JNI является крупным источником сбоев. Вы также можете аварийно завершить работу, используя интерфейс JVMTI, так как он также должен быть написан на C / C ++.

2 голосов
/ 14 сентября 2017

Если вы создадите процесс потока, который бесконечно порождает больше потоков (которые порождают больше потоков, что ...), вы в конечном итоге вызовете ошибку переполнения стека в самой JVM.

public class Crash {
    public static void main(String[] args) {

        Runnable[] arr = new Runnable[1];
        arr[0] = () -> {

            while (true) {
                new Thread(arr[0]).start();
            }
        };

        arr[0].run();
    }
}

Это дало мне вывод (через 5 минут следи за своим бараном)

An unrecoverable stack overflow has occurred.
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_STACK_OVERFLOW (0xc00000fd) at pc=0x0000000070e53ed7, pid=12840, tid=0x0000000000101078
#
# JRE version: Java(TM) SE Runtime Environment (8.0_144-b01) (build 1.8.0_144-b01)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.144-b01 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...