SQL Server JDBC: невозможно создать новый собственный поток

Мы используем драйвер Microsoft sqljdbc 1.2 в сочетании с Hibernate под Windows. Иногда мы получаем OutOfMemoryError от драйвера JDBC, хотя в куче JVM все еще доступно много памяти. Вот трассировка стека исключения, которое мы получаем:

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)

Возможно ли, что sqljdbc пропускает собственные потоки?


person sakra    schedule 15.09.2009    source источник


Ответы (2)


Согласно этой теме, использование setQueryTimeout на statement делает executeQuery открытым поток для каждого запроса. Это может привести к массовому использованию потоков драйвером и вызвать проблемы с памятью. Не уверен, что это так, и не уверен, что это все равно находится под вашим контролем. Так что на самом деле вам, возможно, придется уменьшить размер стека потоков, чтобы избежать этой проблемы.

Попробуйте добавить -Xss128k в настройки JVM.

См. эту тему и это для получения дополнительной информации о размерах стека потоков и аппаратных ограничениях.

person Pascal Thivent    schedule 15.09.2009
comment
Проблема действительно была вызвана setQueryTimeout, который мы использовали в операторах SQL. Интересно, что эти потоки тайм-аута не собираются сразу, даже если соответствующий запрос уже завершен. - person sakra; 16.09.2009
comment
это очень хороший ответ. К сожалению, ссылки в ответе указывают на forums.sun.com, который теперь перенесен на forums.oracle.com без какой-либо возможности поиска старых идентификаторов потоков sun. У кого-нибудь есть ссылки на эти темы в новом разделе форума? - person neesh; 19.01.2011

Меня предостерегали от использования этого драйвера. я цитирую:

Гораздо лучше было бы использовать jTDS, так как собственный драйвер Microsoft не поддерживается Hibernate и имеет некоторые проблемы, которые делают его плохим выбором.

Предпочтительным драйвером для Hibernate на SqlServer является jTDS http://jtds.sourceforge.net/.

person KLE    schedule 15.09.2009