Java 你如何使 JVM 崩溃?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/65200/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 07:51:22  来源:igfitidea点击:

How do you crash a JVM?

javajvm

提问by Shivasubramanian A

I was reading a book on programming skills wherein the author asks the interviewee, "How do you crash a JVM?" I thought that you could do so by writing an infinite for-loop that would eventually use up all the memory.

我正在读一本关于编程技巧的书,其中作者问受访者:“你如何使 JVM 崩溃?” 我认为您可以通过编写一个最终会耗尽所有内存的无限 for 循环来实现。

Anybody has any idea?

有人有什么想法吗?

采纳答案by Leigh Caldwell

The closest thing to a single "answer" is System.exit()which terminates the JVM immediately without proper cleanup. But apart from that, native code and resource exhaustion are the most likely answers. Alternatively you can go looking on Sun's bug tracker for bugs in your version of the JVM, some of which allow for repeatable crash scenarios. We used to get semi-regular crashes when approaching the 4 Gb memory limit under the 32-bit versions (we generally use 64-bit now).

最接近单个“答案”的是System.exit()在没有适当清理的情况下立即终止 JVM。但除此之外,本机代码和资源耗尽是最有可能的答案。或者,您可以在 Sun 的错误跟踪器上查找您的 JVM 版本中的错误,其中一些允许可重复的崩溃场景。在 32 位版本(我们现在通常使用 64 位)下接近 4 Gb 内存限制时,我们曾经遇到半定期崩溃。

回答by Dan Dyer

JNI. In fact, with JNI, crashing is the default mode of operation. You have to work extra hard to get it not to crash.

JNI。事实上,对于 JNI,崩溃是默认的操作模式。你必须加倍努力才能让它不崩溃。

回答by Herms

Depends on what you mean by crash.

取决于你所说的崩溃是什么意思。

You can do an infinite recursion to make it run out of stack space, but that'll crash "gracefully". You'll get an exception, but the JVM itself will be handling everything.

您可以进行无限递归以使其耗尽堆栈空间,但这会“优雅地”崩溃。你会得到一个异常,但 JVM 本身会处理一切。

You can also use JNI to call native code. If you don't do it just right then you can make it crash hard. Debugging those crashes is "fun" (trust me, I had to write a big C++ DLL that we call from a signed java applet). :)

您还可以使用 JNI 来调用本机代码。如果你做的不正确,那么你可以让它崩溃。调试这些崩溃是“有趣的”(相信我,我必须编写一个大的 C++ DLL,我们从一个签名的 Java 小程序调用它)。:)

回答by Mike Stone

If you change that infinite for loop to a recursive call to the same function, then you would get a stack overflow exception:

如果将无限循环更改为对同一函数的递归调用,则会出现堆栈溢出异常:

public static void main(String[] args) {
    causeStackOverflow();
}

public void causeStackOverflow() {
    causeStackOverflow();
}

回答by Dave L.

A perfect JVM implementation will never crash.

完美的 JVM 实现永远不会崩溃。

To crash a JVM, aside from JNI, you need to find a bug in the VM itself. An infinite loop just consumes CPU. Infinitely allocating memory should just cause OutOfMemoryError's in a well built JVM. This would probably cause problems for other threads, but a good JVM still should not crash.

要使 JVM 崩溃,除了 JNI 之外,您还需要在 VM 本身中找到错误。无限循环只会消耗 CPU。无限分配内存只会在构建良好的 JVM 中导致 OutOfMemoryError。这可能会导致其他线程出现问题,但一个好的 JVM 仍然不应该崩溃。

If you can find a bug in the source code of the VM, and for example cause a segmentation fault in the memory usage of the implementation of the VM, then you can actually crash it.

如果你能在 VM 的源代码中发现一个 bug,例如导致 VM 实现的内存使用中的分段错误,那么你实际上可以使它崩溃。

回答by Dave L.

The book Java Virtual Machineby Jon Meyer has an example of a series of bytecode instructions that caused the JVM to core dump. I can't find my copy of this book. If anyone out there has one please look it up and post the answer.

Jon Meyer所著的《Java 虚拟机》一书中有一个示例,说明了一系列导致 JVM 核心转储的字节码指令。我找不到这本书的副本。如果有人在那里,请查找并发布答案。

回答by ralfs

I wouldn't call throwing an OutOfMemoryError or StackOverflowError a crash. These are just normal exceptions. To really crash a VM there are 3 ways:

我不会将抛出 OutOfMemoryError 或 StackOverflowError 称为崩溃。这些只是正常的例外。要真正使 VM 崩溃,有 3 种方法:

  1. Use JNI and crash in the native code.
  2. If no security manager is installed you can use reflection to crash the VM. This is VM specific, but normally a VM stores a bunch of pointers to native resources in private fields (e.g. a pointer to the native thread object is stored in a long field in java.lang.Thread). Just change them via reflection and the VM will crash sooner or later.
  3. All VMs have bugs, so you just have to trigger one.
  1. 使用 JNI 并在本机代码中崩溃。
  2. 如果未安装安全管理器,您可以使用反射使 VM 崩溃。这是 VM 特定的,但通常 VM 在私有字段中存储一堆指向本机资源的指针(例如,指向本机线程对象的指针存储在java.lang.Thread的 long 字段中)。只需通过反射更改它们,VM 迟早会崩溃。
  3. 所有的虚拟机都有错误,所以你只需要触发一个。

For the last method I have a short example, which will crash a Sun Hotspot VM quiet nicely:

对于最后一种方法,我有一个简短的示例,它可以很好地使 Sun Hotspot VM 安静地崩溃:

public class Crash {
    public static void main(String[] args) {
        Object[] o = null;

        while (true) {
            o = new Object[] {o};
        }
    }
}

This leads to a stack overflow in the GC so you will get no StackOverflowError but a real crash including a hs_err* file.

这会导致 GC 中的堆栈溢出,因此您不会得到 StackOverflowError,而是真正的崩溃,包括一个 hs_err* 文件。

回答by eckes

If you define a crash as an process abort because of a unhandled situation (i.e. no Java Exception or Error), then this can not be done from within Java (unless you have permission to use the sun.misc.Unsafe class). This the whole point of managed code.

如果您将崩溃定义为由于未处理的情况(即没有 Java 异常或错误)而导致进程中止,那么这不能从 Java 内部完成(除非您有权使用 sun.misc.Unsafe 类)。这是托管代码的重点。

Typical crashes in native code happen by de-referencing pointers to wrong memory areas (null address or missaligned). Another source could be illegal machine instructions (opcodes) or unhandled signals from library or kernel calls. Both can be triggered if the JVM or the system libraries have bugs.

本机代码中的典型崩溃是通过取消引用指向错误内存区域(空地址或未对齐)的指针而发生的。另一个来源可能是非法机器指令(操作码)或来自库或内核调用的未处理信号。如果 JVM 或系统库有错误,两者都会被触发。

For example JITed (generated) code, native methods or system calls (graphics driver) can have problems leading to real crashes (it was quite common to get a crash when you used ZIP functions and they ran out of memory). In those cases the crash handler of the JVM kicks in and dumps the state. It could also generate a OS core file (Dr. Watson on Windows and core dump on *nix).

例如,经过 JIT 处理的(生成的)代码、本机方法或系统调用(图形驱动程序)可能会出现导致真正崩溃的问题(当您使用 ZIP 函数并且它们耗尽内存时发生崩溃是很常见的)。在这些情况下,JVM 的崩溃处理程序启动并转储状态。它还可以生成操作系统核心文件(Windows 上的 Watson 博士和 *nix 上的核心转储)。

On Linux/Unix you can easyly make a JVM crash by sending it a Signal to the running process. Note: you should not use SIGSEGVfor this, since Hotspot catches this signal and re-throws it as a NullPointerException in most places. So it is better to send a SIGBUSfor example.

在 Linux/Unix 上,您可以通过向正在运行的进程发送一个 Signal 来轻松地使 JVM 崩溃。注意:你不应该使用SIGSEGV它,因为 Hotspot 捕捉到这个信号并在大多数地方将它作为 NullPointerException 重新抛出。所以最好发送一个SIGBUS例子。

回答by eckes

on winxpsp2 w/wmp10 jre6.0_7

在 winxpsp2 上 wmp10 jre6.0_7

Desktop.open(uriToAviOrMpgFile)

Desktop.open(uriToAviOrMpgFile)

This causes a spawned thread to throw an uncaught Throwable and crashes hotspot

这会导致生成的线程抛出未捕获的 Throwable 并导致热点崩溃

YMMV

青年会

回答by eckes

here is a detailed explanation on what causes JVM to core dump (i.e. crash): http://kb.adobe.com/selfservice/viewContent.do?externalId=tn_17534

这里详细解释了导致 JVM 核心转储(即崩溃)的原因:http: //kb.adobe.com/selfservice/viewContent.do?externalId=tn_17534