2011-03-16 22 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; 
    } 
    } 

相关问题