Напишите код Java для сбоя виртуальной машины Java - PullRequest
5 голосов
/ 14 октября 2011

В одном из моих прошлых интервью кто-то попросил меня написать код для сбоя JVM.Я сказал System.exit ().Это правильно?Есть ли лучшие ответы?

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

Ответы [ 5 ]

18 голосов
/ 14 октября 2011

Вы можете использовать класс Unsafe, который небезопасен для использования, как вы можете догадаться.

public static void main(String... args) throws Exception {
    getUnsafe().getByte(0);
}

private static Unsafe getUnsafe() throws NoSuchFieldException, IllegalAccessException {
    Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
    theUnsafe.setAccessible(true);
    return (Unsafe) theUnsafe.get(null);
}

печать

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007ff1c2f23368, pid=2630, tid=140676351506176
#
# JRE version: 7.0-b147
# Java VM: Java HotSpot(TM) 64-Bit Server VM (21.0-b17 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# V  [libjvm.so+0x82c368]  Unsafe_GetNativeByte+0xa8
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /nfs/peter/IdeaProjects/scratch/hs_err_pid2630.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.sun.com/bugreport/crash.jsp
#

Я использовал это, чтобы проверить, когда в файл было внесено изменение. Я внес изменения и разбил JVM, чтобы убедиться, что что-то еще не было сброшено или что-то позже. Затем я проверяю, увидел ли я ожидаемое обновление.

16 голосов
/ 14 октября 2011

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

  • Вызывает ли переполнение стека или счетчик состояния нехватки памяти?
  • Можно ли использовать JNI или любой другой родной код?
  • Скажите мне, какую точную версию VM вы используете, и я попытаюсь найти ошибку компилятора JIT ...

(Конечно, в компиляторе JIT были проблемы вв прошлом - много лет назад у меня была чистая программа на Java, которая последовательно работала бы с segfault, но могла быть «исправлена», делая то, что выглядело как неактивное изменение.)

5 голосов
/ 14 октября 2011

Простота: либо уничтожьте стек бесконечной рекурсией, либо запустите JVM из кучи объектов.

Более сложным было бы запустить JVM из внутренней кучи - вы, вероятно, могли бы сделать это с помощью некоторого цикла загрузки классов, но это потребовало бы работы.

В противном случае вам придется использовать какую-то ошибку или хотя бы заглянуть в JNI.

public class Recur {
public static void main(String[] argv) {
    recur();
}
static void recur() {
    Object[] o = null;
    try {
        while(true) {
            Object[] newO = new Object[1];
            newO[0] = o;
            o = newO;
        }
    }
    finally {
        recur();
    }
}
}

C:\JavaTools>java Recur
#
# An unexpected error has been detected by Java Runtime Environment:
#
#  EXCEPTION_STACK_OVERFLOW (0xc00000fd) at pc=0x000000006dad5c3d, pid=6816, tid
=5432
#
# Java VM: Java HotSpot(TM) 64-Bit Server VM (11.2-b01 mixed mode windows-amd64)

# Problematic frame:
# V  [jvm.dll+0x2e5c3d]
#
# An error report file with more information is saved as:
# C:\JavaTools\hs_err_pid6816.log
#
# If you would like to submit a bug report, please visit:
#   http://java.sun.com/webapps/bugreport/crash.jsp
#

Та да !!

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

0 голосов
/ 28 июля 2015

Чтобы разбить весь компьютер, я бы сделал:

public static void crashComputer() {
    while(true) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                while(true) {
                    crashComputer();
                }
            }
        });
        thread.start();
    }
}

public static void crashJVM() {
    while(true)
        crashJVM();
}

Функция crashComputer занимает около 2 секунд, чтобы разбить весь компьютер.Вы можете остановить его сбой, удерживая кнопку питания.

Функция crashJVM разбила только JVM, перегружая стек, вызывая переполнение стека (отсюда и название этого сайта).* ВНИМАНИЕ: Используйте на свой страх и риск.Это не повредит вашему компьютеру, но я не возьму вину на себя, если вы забудете нажать «Сохранить» на документе или чем-то подобном.

0 голосов
/ 05 августа 2013

Сбой приложения также можно выполнить с помощью OutOfMemoryError.

public class StringOutOfMemory {
    public static void main(String[] args) {
        int i = 0;
        StringBuilder s = new StringBuilder("a");
        while (true) {
            s.append("ahgsdgjsdffsdfhsdgfsdfsdsfhdsgksdgkfgsdkfkdghfksdkfsdkfdkjfskdfkjsdfkdksdkdfjksjkhsdfjkfsdkjfsdhjkfsdjkfhdjkfkjsdfkjdsjkfd");
            System.out.println(i++); 
        }
    }
}

Выход:

java.lang.OutOfMemoryError}}}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...