views:

355

answers:

2

We are using Microsoft's sqljdbc driver 1.2 in combination with Hibernate under Windows. Occasionally we are getting an OutOfMemoryError from the JDBC driver although plenty of memory is still available in the JVM heap. Here's a stack trace of the exception we are getting:

java.lang.OutOfMemoryError: unable to create new native thread
    at java.lang.Thread.start0(Native Method)
    at java.lang.Thread.start(Thread.java:597)
    at com.microsoft.sqlserver.jdbc.TimeoutTimer.start(Unknown Source)
    at com.microsoft.sqlserver.jdbc.TDSCommand.startResponse(Unknown Source)
    at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(Unknown Source)
    at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(Unknown Source)
    at com.microsoft.sqlserver.jdbc.TDSCommand.execute(Unknown Source)
    at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(Unknown Source)
    at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(Unknown Source)
    at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(Unknown Source)
    at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeQuery(Unknown Source)
    at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery(NewProxyPreparedStatement.java:76)
    at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:208)
    at org.hibernate.loader.Loader.getResultSet(Loader.java:1808)
    at org.hibernate.loader.Loader.doQuery(Loader.java:697)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
    at org.hibernate.loader.Loader.doList(Loader.java:2228)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2125)
    at org.hibernate.loader.Loader.list(Loader.java:2120)
    at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:118)
    at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1596)
    at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:306)

Is it possible that sqljdbc leaks native threads?

+2  A: 

I was warned against using this driver. I cite:

Far better would be to use jTDS, since Microsoft's own driver is not supported by Hibernate and has some issues which make it a poor choice.

The favored driver for Hibernate on SqlServer is jTDS http://jtds.sourceforge.net/

KLE
Unfortunately, jTDS doesn't support failover...
Ben
+1  A: 

According to this thread, the use of setQueryTimeout on the statement makes the executeQuery open a thread for each query. This can lead to a massive threads usage by the driver and cause memory problems. Not sure it's the case here and not sure it's under your control anyway. So actually, you may have to reduce the Thread stack size to avoid this problem.

Try to add -Xss128k to your JVM settings.

See this thread and this one for more informations on Thread stack sizing and hardware limitations.

Pascal Thivent
The problem was indeed caused by the setQueryTimeout we were using on SQL statements. Interestingly it seems that these timeout threads are not garbage collected immediately even if the corresponding query has already finished.
sakra