在我过去的一次采访中,有人让我写一个代码来破坏JVM。我说System.exit()。它是否正确?还有更好的答案吗?
澄清:我可以在开发和部署期间包含我的代码。并不是JVM已经在运行,我必须编写一个黑客代码来破坏其他JVM。
答案 0 :(得分:18)
您可以像使用猜测一样使用不安全的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,以确保其他东西没有冲洗或稍后。然后我检查我看到了我预期的更新。
答案 1 :(得分:16)
我不认为礼貌地请求JVM终止真的被视为“崩溃”它。你必须要求面试者完全他们的意思是“崩溃”。例如:
(过去肯定存在JIT编译器问题 - 很久以前我有一个纯Java程序,它会一直是段错误,但可以通过制作看似无操作的变化来“修复”。)
答案 2 :(得分:5)
简单:用无限递归来破坏堆栈或者从对象堆中运行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:\JavaTools\hs_err_pid6816.log
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
#
Ta da !!
(并且您可以限制对不安全的访问,但不能限制以上任何一种。)
答案 3 :(得分:0)
要使整台计算机崩溃,我会这样做:
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,导致堆栈溢出(这个网站的名称来自哪里)。
警告:使用风险由您自行承担。这不会损坏您的计算机,但如果您忘记单击保存在文档或其他内容,我就不会受到指责。
答案 4 :(得分:-1)
也可以使用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}}}