错误:
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();
}
最佳答案
您生成了太多线程,并且超出了操作系统施加的限制。产生大量线程的原因可能是因为每次使用数据库连接时都要实例化一个新的连接池。尝试将实例化一次连接池到静态字段(final static ComboPooledDataSource pool
)上。
但是请注意,共享连接池引用的推荐方法是使用依赖注入框架,例如Spring或Guice。