2011-03-16 75 views
0

我剛剛有一個Web應用程序在幾分鐘後掛起。基本上,這是一個構建和預覽表單的應用程序,非常自定義,並且經過幾分鐘的密集用戶交互之後,應用程序才停止工作。這意味着,一個請求完成,永遠不會返回一個答覆。Web應用程序在tomcat 6.0.21/7.0.11中無法線索

由於我在tomcat日誌和應用程序日誌中找不到關於掛起的任何線索,所以我「有點」迷失了。應用程序服務器正在運行,因爲我使用的是lambda/psi-probe,並且可以檢查其他甚至是麻煩的應用程序(探針本身是另一個Web應用程序)。

該應用程序使用hibernate,它工作良好很長一段時間,最近,以提高性能(休眠注入大量的查詢,如果你專門用它)我已經通過java.sql標準api引入本機sql 。我小心不要混淆兩者,它們只用於jsp,首先使用hibernate檢索一些(少數)對象,然後使用jdbc使用某些邏輯。在使用jdbc之前關閉Hibernate會話。

我已經閱讀了有關數據庫連接問題(我已經檢查過好幾次,數據庫服務器運行正常),死鎖或失控線程,使用VisualVM中的VisualVM進行檢查。

那麼,任何人都可以提供關於尋找或陷阱的線索?可以提供一些線索來使用VisualVM捕捉或捕獲假想的失控線程或死鎖?後者會啓發我,因爲我只看到等待和運行的線程。

我使用Tomcat 6.0.21(我總是試圖用7.0.11相同的結果)在Mac OSX和Linux(在開發和預機)的Java 1.6

任何想法將受到歡迎確保 感謝

willy

回答

1

嘗試運行jconsole(如果您無法在遭遇掛起的計算機上執行此操作,則需要啓用遠程JMX,重新啓動JVM並重新掛起),然後單擊線程選項卡,然後單擊檢測死鎖。這可能會提供一些幫助。

其他可以使用的東西,如您所說,VisualVM或JCarder

編輯

看到您的評論後,另一件事是嘗試以下操作:

  1. 啓動JConsole的,並連接到您的雄VM
  2. 導航到的MBean → com.sun.management → HotSpotDiagnostic →操作
  3. 將會有一個按鈕叫做dumpHeap帶有兩個文本框在它旁邊。在第一個文本框中,輸入一個唯一的名稱 - 我使用類似於我的姓名縮寫和日期 - rt20110317。保持第二個文本框設置爲true。點擊dumpHeap按鈕。

這會將堆寫入大文件。找到這個文件並加載到Eclipse MAT。這個工具爲查看虛擬機的狀態提供了各種有用的資料。甚至有幾個尋找內存泄漏的嚮導,這些嚮導也可能會找到原因,如果它是由於相同類型的症狀導致虛擬機掛起的原因。

+0

抱歉,它沒有提供任何新的東西,應用程序掛起,我沒有看到任何顯着的 – 2011-03-16 17:09:54

+0

@willy我已經添加了另一個建議 – Rich 2011-03-17 13:00:30

1

我一直處於與此類似的狀況。問題是某些數據庫連接從未返回到連接池。達到限制後,應用程序將凍結,沒有任何例外或錯誤。你也可能是這種情況。在您的連接池中打開放棄的連接日誌記錄,您可能需要檢查是否存在任何流氓連接。

+0

我也有類似的問題..它是一個錯誤在湯姆CAT6? – KronnorK 2011-05-14 17:30:36

+0

@KronnorK更可能是它的開發者代碼的一個錯誤 – 2011-05-14 18:49:51

+0

有什麼對你們有用嗎?我有同樣的問題我的應用程序在12-18小時後停止響應 – 2013-07-28 15:24:33

0

確保您關閉任何JDBC調用是這樣的: 參考:http://tomcat.apache.org/tomcat-6.0-doc/jndi-datasource-examples-howto.html#Preventing_dB_connection_pool_leaks

下面是正確編寫的代碼示例使用從連接池中得到一個數據庫連接:

Connection conn = null; 
    Statement stmt = null; // Or PreparedStatement if needed 
    ResultSet rs = null; 
    try { 
    conn = ... get connection from connection pool ... 
    stmt = conn.createStatement("select ..."); 
    rs = stmt.executeQuery(); 
    ... iterate through the result set ... 
    rs.close(); 
    rs = null; 
    stmt.close(); 
    stmt = null; 
    conn.close(); // Return to connection pool 
    conn = null; // Make sure we don't close it twice 
    } catch (SQLException e) { 
    ... deal with errors ... 
    } finally { 
    // Always make sure result sets and statements are closed, 
    // and the connection is returned to the pool 
    if (rs != null) { 
     try { rs.close(); } catch (SQLException e) { ; } 
     rs = null; 
    } 
    if (stmt != null) { 
     try { stmt.close(); } catch (SQLException e) { ; } 
     stmt = null; 
    } 
    if (conn != null) { 
     try { conn.close(); } catch (SQLException e) { ; } 
     conn = null; 
    } 
    } 

相關問題