2009-09-15 7 views
0

Nous utilisons le pilote sqljdbc de Microsoft 1.2 en combinaison avec Hibernate sous Windows. Parfois, nous obtenons une OutOfMemoryError à partir du pilote JDBC bien que beaucoup de mémoire soit toujours disponible dans le tas JVM. Voici une trace de la pile de l'exception que nous obtenons:SQL Server JDBC: impossible de créer un nouveau thread natif

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) 

Est-il possible que les fuites sqljdbc threads natifs?

Répondre

1

Selon this thread, l'utilisation de setQueryTimeout sur la statement rend le executeQuery ouvrir un thread pour chaque requête. Cela peut entraîner une utilisation massive des threads par le pilote et provoquer des problèmes de mémoire. Je ne suis pas sûr que ce soit le cas ici et je ne suis pas sûr que ce soit sous votre contrôle de toute façon. Donc en fait, vous devrez peut-être réduire la taille de la pile Thread pour éviter ce problème.

Essayez d'ajouter -Xss128k à vos paramètres JVM.

Voir this thread et this one pour plus d'informations sur le dimensionnement de la pile de threads et les limitations matérielles.

+0

Le problème était en effet dû au paramètre setQueryTimeout que nous utilisions sur les instructions SQL. Il est intéressant de noter que ces threads de timeout ne sont pas collectés immédiatement, même si la requête correspondante est déjà terminée. – sakra

+0

c'est une très bonne réponse. Malheureusement, les liens dans le point de réponse à forums.sun.com qui a maintenant été migré sur forums.oracle.com sans aucun moyen de rechercher les anciens identifiants de threads Sun. Quelqu'un at-il des liens vers ces sujets dans la nouvelle section des forums? – neesh

2

J'ai été mis en garde contre l'utilisation de ce pilote. Je cite:

Il vaut beaucoup mieux serait d'utiliser jTDS, car propre pilote de Microsoft ne sont pas pris en charge par Hibernate et a quelques problèmes qui en font un mauvais choix.

Le conducteur privilégié pour Hibernate sur SqlServer est jTDS http://jtds.sourceforge.net/

+0

Malheureusement, jTDS ne prend pas en charge le basculement ... – Ben

Questions connexes