2010-07-16 3 views
0

Actuellement j'utilise statement.executeQuery(qStr) en Java pour sélectionner une grande quantité de données de mysql. Malheureusement, Java manque de mémoire à l'instruction statement.executeQuery(qStr) avec l'exception java.lang.OutOfMemoryError: Java heap space. Je me demande s'il existe une méthode pour diffuser les données de chargement de mysql. Alors que je peux gérer le tronc de données sélectionné par tronc pour éviter de manquer de mémoire?Puis-je charger le tronc de données mysql par le tronc dans java?

Notez que: J'utilise eclipse et ce post me montre comment augmenter la mémoire de tas pour java à utiliser dans eclipse. Mais après avoir suivi sa méthode, je suis toujours confronté au même problème.

Merci d'avance.

Répondre

1

Oui, vous pouvez définir le FetchSize sur une déclaration à Integer.MIN_VALUE, le ResultSet doit également être TYPE_FORWARD_ONLY, bien que je pense que c'est la valeur par défaut .. MySQL traite spécialement et active le streaming du ResultSet au lieu de le lire tout en mémoire, il est documenté here

PreparedStatement stmt = 
conn.prepareStatement(sql,ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_READ_ONLY); 
stmt.setFetchSize(Integer.MIN_VALUE); 
+0

Merci les gars pour vos réponses. Je l'ai essayé mais sort avec une autre exception: "com.mysql.jdbc.RowDataDynamic $ OperationNotSupportedException: opération non prise en charge pour l'ensemble de résultats de diffusion". J'utilise mysql-connector-java-5.1.13-bin.jar. En outre, si j'ai remplacé Integer.MIN_VALUE par un nombre spécifique 100. Ensuite, l'exception de mémoire hors pile s'affiche toujours. Une idée? Merci. – Ken

+0

Integer.MIN_VALUE est spécial dans mysql, le paramétrer sur n'importe quoi d'autre donne le comportement par défaut. Je ne sais pas où vous obtenez cette exception - alors postez le code où cela arrive. – nos

+0

Merci nos, j'essayais d'extraire le code relavent passé ici, puis j'ai trouvé la source du problème. c'est le problème d'appeler le resultSet.getRow() ...... Ok .. c'est pour m'aider .. j'apprécie pour votre aide. Merci. – Ken

1

Par défaut, ResultSets sont complètement récupérées et stockées dans la mémoire. Si vous avez affaire à d'énormes ensembles de résultats, votre tas sera rapidement épuisé. Vous pouvez modifier ce comportement en créant l'instance de déclaration comme ceci:

stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, 
      java.sql.ResultSet.CONCUR_READ_ONLY); 
stmt.setFetchSize(Integer.MIN_VALUE); 

Cela crée un

avant uniquement, en lecture seule l'ensemble de résultats, avec une taille d'extraction de Integer.MIN_VALUE sert signale au pilote de diffuser les ensembles de résultats ligne par ligne. Après cela, tous les ensembles de résultats créés avec l'instruction seront récupérés ligne par ligne.

Voir la documentation MySQL pour plus de détails et les mises en garde: http://dev.mysql.com/doc/refman/5.5/en/connector-j-reference-implementation-notes.html

+0

Merci les gars pour vos réponses. Je l'ai essayé mais sort avec une autre exception: "com.mysql.jdbc.RowDataDynamic $ OperationNotSupportedException: opération non prise en charge pour l'ensemble de résultats de diffusion". J'utilise mysql-connector-java-5.1.13-bin.jar. En outre, si j'ai remplacé Integer.MIN_VALUE par un nombre spécifique 100. Ensuite, l'exception de mémoire hors pile s'affiche toujours. Une idée? Merci. – Ken

+0

Pour MySQL, vous devez définir la taille d'extraction sur Integer.MIN_VALUE, sinon le pilote revient à la stratégie de mise en cache habituelle de ResultSets. –

+0

L'exception OperationNotSupportedException peut avoir plusieurs raisons. Pour commencer, quelle version de MySQL utilisez-vous (il existe un bug connu avec la version 5.1.6)? –