在我过去的一次面试中,有人让我编写一个使JVM崩溃的代码。我说的是System.exit()。这是正确的吗?有更好的答案吗?
澄清:我可以在开发和部署期间包含我的代码片段。这并不是说JVM已经在运行,我必须编写一个黑客代码来崩溃另一个JVM。
您可以使用不安全的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崩溃,以确保其他东西不会刷新或稍后发生的事情。
我不认为礼貌地请求JVM终止真的算作"崩溃"它。你得问面试官他们说的"崩溃"到底是什么意思。例如:
- 将强制堆栈溢出或内存不足的条件计数?
- 你可以使用JNI或任何其他类型的本机代码吗?
- 告诉我你正在运行的确切的 VM版本,我会试着找到一个JIT编译器的错误…
(过去肯定有JIT编译器的问题——很久以前我有一个纯Java程序,它总是会出现段错误,但可以通过做一个看起来像无操作的改变来"修复"。)
简单:要么用无限递归破坏堆栈,要么让JVM耗尽对象堆。
更复杂的是在内部堆中运行JVM——您可以通过某种类型的类加载循环来做到这一点,但这将花费更多的工作。
否则你必须利用某种bug,或者至少进入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:JavaToolshs_err_pid6816.log
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
#
Ta哒! !
(您可以限制对不安全的访问,但不能限制上述任何访问)
要使整个计算机崩溃,我会这样做:
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();
}
crash computer功能大约需要2秒才能使整个计算机崩溃。按住电源键可以防止死机
crashJVM函数只通过重载堆栈导致JVM崩溃,导致堆栈溢出(这就是这个网站的名字的来源)。
警告:使用风险自负。这不会损坏你的电脑,但如果你忘记在文件或其他地方点击保存,我不会承担责任。
也可以使用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}}}