同时访问servlet时的OutOfMemoryError

时间:2012-12-23 22:44:25

标签: java jdbc

错误:

java.lang.OutOfMemoryError: unable to create new native thread
    java.lang.Thread.start0(Native Method)
    java.lang.Thread.start(Unknown Source)
    java.util.Timer.<init>(Unknown Source)
    com.mchange.v2.c3p0.impl.C3P0PooledConnectionPoolManager.poolsInit(C3P0PooledConnectionPoolManager.java:158)
    com.mchange.v2.c3p0.impl.C3P0PooledConnectionPoolManager.<init>(C3P0PooledConnectionPoolManager.java:283)
    com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getPoolManager(AbstractPoolBackedDataSource.java:508)
    com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:128)

同时访问servlet时发生上述错误

更新: Java代码:

public class MyServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;
    private static final Log LOGGER = LogFactory.getLog(MyServlet.class);

   private void doRequest(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {

        CallableStatement stmt = null;
        ResultSet rs = null;

        Connection conn = null;
        try {

            conn = getConnection();

            stmt = conn.prepareCall("{call sp_SomeSPP(?)}");
            stmt.setLong(1, getId());

            rs = stmt.executeQuery();

            // set mime type
            while (rs.next()) {
                if (rs.getInt(1)==someValue()) {
                    doStuff();
                    break;
                }
            }


        // ADD THESE LINES
        if (rs != null) { rs.close(); rs = null; }
        if (stmt != null) { stmt.close(); stmt = null; }


            stmt = conn.prepareCall("{call sp_SomeSP(?)}");
            stmt.setLong(1, getId());

            rs = stmt.executeQuery();
            if (rs.next()) {
                // do stuff
            }

            RequestDispatcher rd = getServletContext().getRequestDispatcher("/SomeJSP.jsp");
            rd.forward(request, response);
            return;
        } catch (NamingException e) {
            LOGGER.error("Database connection lookup failed", e);
        } catch (SQLException e) {
            LOGGER.error("Query failed", e);
        } catch (IllegalStateException e) {
            LOGGER.error("View failed", e);
        } finally {
            try {
                if (rs!=null && !rs.isClosed()) {
                    rs.close(); 
                }
            } catch (NullPointerException e) {
                LOGGER.error("Result set closing failed", e);
            } catch (SQLException e) {
                LOGGER.error("Result set closing failed", e);
            }
            try {
                if (stmt!=null) stmt.close();
            } catch (NullPointerException e) {
                LOGGER.error("Statement closing failed", e);
            } catch (SQLException e) {
                LOGGER.error("Statement closing failed", e);
            }
            try {
                if (conn != null){
                    conn.close();
                    conn = null;
                }
            } catch (NullPointerException e) {
                LOGGER.error("Database connection closing failed", e);
            } catch (SQLException e) {
                LOGGER.error("Database connection closing failed", e);
            }
        }

   }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doRequest(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doRequest(request, response);
    }

    protected static Connection getConnection() throws NamingException, SQLException {
    ComboPooledDataSource cpds = new ComboPooledDataSource();
    try {
        cpds.setDriverClass( "net.sourceforge.jtds.jdbc.Driver" ); //loads the jdbc driver     
        cpds.setJdbcUrl( "jdbc:jtds:sqlserver://10.38.28.77/MyDB" );   
        cpds.setUser("sa");                                  
        cpds.setPassword("password");   
        cpds.setMaxStatements( 180 );
    } catch (PropertyVetoException e) {
        e.printStackTrace();
    }      
    return cpds.getConnection();
    }

1 个答案:

答案 0 :(得分:1)

您正在产生太多线程并超出操作系统施加的限制。产生如此多线程的原因可能是因为每次使用数据库连接时都要实例化一个新的连接池。尝试将连接池一次实例化到静态字段(final static ComboPooledDataSource pool)上。

但是请注意,共享连接池引用的推荐方法是使用依赖注入框架,如Spring或Guice。