代码之家  ›  专栏  ›  技术社区  ›  Satbir

Java程序崩溃了吗?

  •  26
  • Satbir  · 技术社区  · 15 年前

    我是一个C++程序员,我对Java有点了解。我知道Java程序员不必像C++那样直接使用内存。我也知道C++应用中的大多数崩溃是由于内存损坏。

    那么Java应用程序是否会因为内存相关问题而崩溃呢?

    谢谢

    12 回复  |  直到 14 年前
        1
  •  49
  •   Konrad Rudolph    15 年前

    与其他一些答案相反,我将声称Java程序会频繁崩溃,甚至可能崩溃。 更多 经常是C++程序。

    通过__crash__,大多数人都知道程序遇到未正确处理的错误,导致应用程序终止。当然,这与Java对待内存的方式无关。

    这是一个 好的 事情。是什么使得C++如此危险,Java相对安全,正是Java的事实。 将崩溃 在C++将愉快地继续运行的情况下,尽管做了非常错误的和潜在的危险的事情(例如写入未初始化的内存、溢出缓冲器、E-YAY)。Java的崩溃(例如抛出异常)可以防止更严重的破坏。另一方面,C++应用程序(由于未能终止错误),可能会对外部数据或系统造成损害。或者他们可能只是提供了一个错误的(但似乎是合理的)结果。

    它对 这些 Java保护的危险,而不是崩溃 本身 .

        2
  •  16
  •   jeff porter ichak khoury    15 年前

    Java可以崩溃。

    原因可能是……

    OutOfMemoryError
    StackoverFlowError
    OutOfMemoryError: PermGen space.
    

    内存不足错误 当Java虚拟机无法分配对象时抛出,因为它内存不足,垃圾回收器无法再提供内存。

    堆栈溢出错误 StackOverflowException是为执行堆栈溢出错误而引发的,通常是在非常深或无限递归的情况下。

    内存不足错误:PermGen空间 详细信息permgen space表示永久代已满。永久生成是堆中存储类和方法对象的区域。如果应用程序加载了大量类,那么可能需要使用-xx:maxpermsize选项来增加永久生成的大小。

    问题是关于可能导致崩溃的内存问题。

    其他可能导致崩溃但可能被程序捕获并从中恢复的问题 积极性 是否有RuntimeExceptions。 即

    算术例外, 数组存储异常, 缓冲区溢出异常, BufferUnderflowException, 无法恢复异常, 无法撤消异常, classcastexception、cmmexception和 当前修改例外, domException、EmptySackException和 IllegalArgumentException,例外, 非法监视器状态异常, 非法路径状态异常, 非法状态例外, 想象异常, indexoutofboundsException, 缺少资源异常, 否定数组大小异常, 无接触异常, 空指针异常, 配置文件数据异常, 提供异常, Raster格式异常, 安全异常,系统异常, 未声明的ThrowableException, 不可修改的例外, UnsupportedOperation异常

    我不会在这里讨论这些。但是看看…… link text

        3
  •  8
  •   chris    15 年前

    是的,它可以:

    public void test() {
        test();
    }
    

    这将与 StackoverFlowError . 还有其他一些-例如内存不足会导致崩溃( OutOfMemoryError )。

        4
  •  2
  •   Niki    15 年前

    C++中的内存损坏不仅仅是发生。它们是由软件错误引起的,比如在数组末尾写入。这样做也会导致Java崩溃。(没有语言会包含包含错误的源代码,并生成一个程序来完成你原本想要的)。不同之处在于C++中你得到了“未定义的行为”,即程序可能会在其他地方崩溃。Java程序将在您试图通过数组末尾写入的时候崩溃,这使得它更容易实现。 找到 臭虫。

        5
  •  1
  •   Marcelo Cantos    15 年前

    Java程序总是崩溃。我遇到的最常见原因是内存耗尽和未处理的异常。

        6
  •  1
  •   Community CDub    8 年前

    当然他们会撞车的:)

    除了所有的问题,答案,还有简单明了的JVM崩溃。例如,我问了一个问题,关于一个使用特定数据集可以可靠崩溃的损坏的JVM的案例(这不是我的错:这 不应该 “发生…但确实如此;

    我见过服务器端的JVM在一些奇怪的情况下崩溃(Tomcat+Hibernate+Sun-VM问题,以前是通过更改Tomcat或Sun-VM来修复的)。

    我看到JVM在桌面上崩溃时,他们不应该(运送商用Java软件到许多台式机往往会增加你目睹这种事情的概率)。

    我所看到的最好的是一个JVM的简单故障,我可以在几台机器上工作时可靠地崩溃,而且,不,这些机器都没有问题,它们是稳定的、可靠的工作站(从那篇文章开始,我在几台机器上尝试过,我可以复制它):

    Java VM: reproducable SIGSEGV on both 1.6.0_17 and 1.6.0_18, how to report?

    (请注意,在同一台机器上,有许多其他的JVM都很好,具有相同的软件/数据集)。

    当我看到一个JVM崩溃时,首先要做的是更改其中一个软件组件:通常将JVM升级到最新版本。

        7
  •  0
  •   Michael Borgwardt    15 年前

    所以用Java编写的应用程序 从不因记忆相关而崩溃 问题。

    OutOfMemoryError 当然是与记忆有关的问题。此外,当遇到JVM中的一个错误(通常是用C或C++编写),或者当存在硬件问题(如坏RAM)时,你会得到一个“实际”崩溃(Sebug)。也可能是在未验证的JVM上运行无效的字节码时(例如,用于嵌入式系统的JVM)。

    但通常情况下,是的,Java程序不分段。

        8
  •  0
  •   AllenJB    15 年前

    不,Java应用程序可能由于内存问题而崩溃。虽然Java有内置内存管理,但它并不完美。只是为你做了很多艰苦的工作。

    正如在其他一些答案中提到的,Java确实有一个相当具体的内存分配系统,它涉及相当多的手工管理,如果你不小心,而且它没有为你的应用程序正确设置,那么它很容易耗尽。

    (向Java看到-Xmx和-XMS参数)

        9
  •  0
  •   Richard H    15 年前

    虽然JVM本身不太可能崩溃,但您的程序完全有可能崩溃于与内存相关的问题,例如,通过永不超出范围的对象的内存泄漏。

    ( 编辑: JVM是一个高度优化的平台,虽然bug非常罕见,但它们仍然偶尔会出现,当然,正如其他人在这里提到的,如果存在硬件问题(如损坏的I/O或RAM),则JVM可以并且将要死亡)

        10
  •  0
  •   fastcodejava    15 年前

    这个程序将抛出 OutOfMemoryException 撞车。

    void crash(List list) {
       while (true) {
          list.add(new Object());
       }
    }
    
        11
  •  0
  •   stacker    15 年前

    一次严重的车祸看起来是这样的:

    #
    # A fatal error has been detected by the Java Runtime Environment:
    #
    #  SIGSEGV (0xb) at pc=0x00000000, pid=3387, tid=166603048020
    #
    # JRE version: 6.0_14-b08
    # Java VM: Java HotSpot(TM) Server VM (14.0-b16 mixed mode linux-x86 )
    # Problematic frame:
    # C  0x00000000
    #
    # An error report file with more information is saved as:
    # .....hs_err_pid3387.log
    

    并不是Java程序导致了这一点,而是VM本身的代码。这几年来非常罕见。

        12
  •  0
  •   Daniel    14 年前

    如果您想测试如果JVM真的崩溃会发生什么,请尝试这个函数(我使用它来测试我的崩溃处理程序:)。不适用于安全环境或非Sun JDK。

    /**
     * Crashes the JVM, by copying 1 byte from address 1 to address 1. If this did
     * not crash the machine already, we copy a byte from -1 to -1 :). Never call 
     * this except for debugging problems related  to handling system crashes.
     */
    public static void crash() {        
        Unsafe unsafe;
        try {
            Field field = Unsafe.class.getDeclaredField("theUnsafe");
            field.setAccessible(true);
            unsafe = (Unsafe)field.get(null);
        } catch (Exception ex) {
            throw new RuntimeException("Can't get Unsafe instance to crash app.", ex);
        }
        log.fatal("Here we are and say good bye, the app ist now about to die...");
        // Crash now!
        unsafe.copyMemory(1,1,1);
        // Still alive? Than the following line will help... Crash now!
        unsafe.copyMemory(-1,-1,1);
    }