0

エラー:

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)

上記のエラーは、サーブレットに同時にアクセスすると発生します

更新: 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();
    }
4

1 に答える 1

1

生成するスレッドが多すぎて、OS によって課された制限を超えています。非常に多くのスレッドを生成する理由は、データベース接続を使用するたびに新しい接続プールをインスタンス化しているためと考えられます。final static ComboPooledDataSource pool代わり に、静的フィールド ( ) に対して接続プールを 1 回インスタンス化してみてください。

ただし、接続プール参照を共有するための推奨される方法は、Spring や Guice などの依存性注入フレームワークを使用することです。

于 2012-12-23T23:11:49.860 に答える