2010-05-19 132 views
26

我是一名C++程序員,我對Java有點了解。我知道Java程序員不必像C++那樣直接使用內存。我也知道在C++應用程序中大多數崩潰是由於內存損壞。Java程序有沒有崩潰?

那麼由於內存相關問題,用Java編寫的應用程序崩潰了嗎?

謝謝

+5

前些天Netbeans中墜毀,機上我,設法取出JVM用,所以是的,他們會崩潰:P – Moonshield 2010-05-19 08:28:41

+3

的Java _programs_運行在JVM可能會崩潰,但JVM通常後正常關閉。 – 2010-05-19 14:38:52

回答

49

與其他一些答案相反,我會聲稱Java程序會經常崩潰,或者甚至可能比C++程序更頻繁地崩潰更多。通過「崩潰」,大多數人都明白程序遇到錯誤,處理不當,導致應用程序終止。那麼,這當然會發生,並且與Java對待內存的方式沒有任何關係。

這是一個的事情。 C++如此危險以及Java相對安全的原因恰恰是,在C++將繼續運行的情況下,Java 將會崩潰,儘管這樣做可能非常錯誤且有潛在危險(例如,寫入未初始化的內存,溢出的緩衝區, ...)。 Java的崩潰(例如拋出異常)可以防止更壞的破壞。另一方面,C++應用程序(由於未能終止錯誤)可能會損壞外部數據或系統。或者他們可能會提供一個錯誤的(但看似合理的)結果。

這是對這些危險的是Java的守衛,不反對崩潰本身

+1

+1未定義的行爲在程序中不是一件好事。 – AraK 2010-05-19 08:40:53

+0

感謝您的回答,它可以幫助我更好地理解 – Satbir 2010-05-19 09:11:36

+1

另一方面,如果您不希望程序繼續運行,並且您絕對想爲計算中的任何潛在錯誤拋出異常,那麼您應該承擔風險爆炸火箭。見第一次阿麗亞娜5發射。 – 2010-05-19 13:49:18

16

java會崩潰。

原因可能是..

OutOfMemoryError 
StackoverFlowError 
OutOfMemoryError: PermGen space. 

的OutOfMemoryError 的時候,因爲它超出了內存,並且可以通過垃圾收集器提供任何更多的內存,Java虛擬機無法分配一個對象時拋出。

的StackOverflowError StackOverflowException拋出供執行堆棧溢出錯誤,通常在非常深的或無限遞歸的情況下。

OutOfMemoryError:PermGen空間 詳細信息PermGen空間表示永久生成已滿。永久代是存儲類和方法對象的堆的區域。如果應用程序加載大量的類,則可能需要使用-XX:MaxPermSize選項增加永久生成的大小。

問題是關於可能導致崩潰的內存問題。

可能導致崩潰但可以被程序捕獲並從posibilty中恢復的其他問題 是任何runtimeExceptions。 即

ArithmeticException, ArrayStoreException, BufferOverflowException, BufferUnderflowException, CannotRedoException, CannotUndoException, ClassCastException, CMMException, ConcurrentModificationException, DOMException, EmptyStackException, IllegalArgumentException, IllegalMonitorStateException, IllegalPathStateException, IllegalStateException, ImagingOpException, IndexOutOfBoundsException, MissingResourceException, NegativeArraySizeException, NoSuchElementException, NullPointerException, ProfileDataException, ProviderException, RasterFormatException, SecurityException, SystemException, UndeclaredThrowableException, UnmodifiableSetException, UnsupportedOperationException

我不會在這裏進入這些。但看看... link text

+1

+1對於Stackoverflow :) – 2010-05-19 08:18:25

+2

你已經忘記了:NullPointerException,幾乎總是從無處來... – Kedare 2010-05-19 08:19:03

+1

有沒有這樣的事情作爲PermGenSpaceException – 2010-05-19 08:20:40

1

Java程序一直崩潰。我遇到的最常見的原因是內存耗盡和未處理的異常。

8

是的,它可以:)

public void test() { 
    test(); 
} 

這將與StackoverFlowError崩潰。還有一些其他的 - 例如內存不足也會導致崩潰(OutOfMemoryError)。

+0

+1 yep雖然這個堆棧溢出與C++緩衝區溢出很不一樣。 – rook 2010-05-19 08:33:14

+2

'StackOverflowError',而不是'StackoverFlowException'。 – Jesper 2010-05-19 08:55:29

+0

不錯的一個jesper,謝謝 – oedo 2010-05-19 13:37:21

0

So an application written in Java will never crash due to memory relate issue.

OutOfMemoryError肯定是內存相關的問題。此外,當遇到JVM中的錯誤(通常用C或C++編寫),或者存在硬件問題(例如錯誤的RAM)時,可能會發生「真正」崩潰(segfault)。可能還會在未驗證它的JVM上運行無效字節碼(例如嵌入式系統的JVM)。

但通常,是的,Java程序不會段錯誤。

0

否由於內存問題,Java應用程序可能會崩潰。雖然Java確實有內置的內存管理,但它絕不是完美的。只是爲你做了很多艱苦的工作。

正如在其他一些答案中提到的那樣,Java確實有一個相當特殊的內存分配系統,它涉及到相當多的手動管理,如果你不小心並且不讓它爲您的應用程序正確設置。

(請參閱-Xmx和-Xms參數到Java)

0

雖然這是不太可能的JVM本身會崩潰這是完全有可能爲你的程序通過從內存泄漏內存相關的問題,例如,通過從未去對象崩潰超出範圍。 JVM是一個高度優化的平臺,儘管bug非常罕見,但它們偶爾會出現,當然,正如其他人在這裏提到的那樣,如果您有硬件問題,如腐敗的I/O或RAM,JVM可能並將死亡)

2

C++中的內存損壞不僅發生。它們是由軟件錯誤引起的,例如寫入數組的末尾。這樣做也會導致Java崩潰。 (任何語言都不會採取包含錯誤的源代碼,並生成一個能夠完成你原先的目標的程序。)不同的是,在C++中,你會得到「未定義的行爲」,即程序可能會在別的地方崩潰。 Java程序會在您嘗試寫入數組末尾的那一刻崩潰,這使得找到錯誤更容易。

0

該程序將拋出OutOfMemoryException並崩潰。

void crash(List list) { 
    while (true) { 
     list.add(new Object()); 
    } 
} 
+5

'OutOfMemoryError',而不是'OutOfMemoryException'。 – Jesper 2010-05-19 08:55:03

+0

您可以捕獲OutOfMemoryError,並清除列表並繼續運行,就好像它從未發生過一樣。所以即使是可能導致程序崩潰的東西也可以在Java中恢復。 – 2010-05-21 21:08:50

1

當然他們這樣做崩潰:)

除了所有的罰款,答案,另外還有一個簡單明瞭的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升級到最新版本。

+0

我不得不提及Java並不穩定:我有兩年正常運行時間的生產服務器(強化的Debian Linux系統往往不需要許多「重要」補丁,強制重啓;)其中運行的Java服務器幾乎不需要重新啓動(它們重新啓動,但不是因爲崩潰和/或內存相關的問題)。 – SyntaxT3rr0r 2010-05-19 15:30:58

0

嚴重崩潰的樣子說:

# 
# 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 PROGRAMM導致此,它是虛擬機本身的代碼。這幾年以來非常罕見。

0

如果你想測試如果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); 
}