JDBC Insertion OutOfMemoryError
J'ai écrit une méthode insert()
dans lequel je suis en train d'utiliser JDBC Lot pour l'insertion d'un demi-million d'enregistrements dans une base de données MySQL:
public void insert(int nameListId, String[] names) {
String sql = "INSERT INTO name_list_subscribers (name_list_id, name, date_added)"+
" VALUES (?, ?, NOW())";
Connection conn = null;
PreparedStatement ps = null;
try{
conn = getConnection();
ps = conn.prepareStatement(sql);
for(String s : names ){
ps.setInt(1, nameListId);
ps.setString(2, s);
ps.addBatch();
}
ps.executeBatch();
}catch(SQLException e){
throw new RuntimeException(e);
}finally{
closeDbResources(ps, null, conn);
}
}
Mais à chaque fois que j'essaie d'exécuter cette méthode, j'obtiens l'erreur suivante:
java.lang.OutOfMemoryError: Java heap space
com.mysql.jdbc.ServerPreparedStatement$BatchedBindValues.<init>(ServerPreparedStatement.java:72)
com.mysql.jdbc.ServerPreparedStatement.addBatch(ServerPreparedStatement.java:330)
org.apache.commons.dbcp.DelegatingPreparedStatement.addBatch(DelegatingPreparedStatement.java:171)
Si je remplace ps.addBatch()
avec ps.executeUpdate()
et supprimer ps.executeBatch()
, il fonctionne très bien, mais il faut un certain temps. S'il vous plaît laissez-moi savoir si vous savez si à l'aide de Lot est approprié dans cette situation, et si elle l'est, pourquoi donne-t-il OurOfMemoryError
?
Grâce
OriginalL'auteur craftsman | 2010-02-09
Vous devez vous connecter pour publier un commentaire.
addBatch
etexecuteBatch
vous donner le mécanisme d'effectuer des insertions, mais vous avez encore besoin de faire le dosage de l'algorithme de vous-même.Si vous avez simplement la pile à chaque instruction dans le même lot, comme vous le faites, alors vous serez à court de mémoire. Vous devez exécuter/effacer le lot de tous les
n
enregistrements. La valeur den
est à vous, JDBC ne pouvez pas prendre cette décision pour vous. Plus la taille du lot, plus vite les choses vont aller, mais trop grand et vous obtiendrez la mémoire de la famine, et les choses vont ralentir ou à l'échec. Ça dépend de combien vous avez de mémoire.Commencer avec une taille de lot de 1000, par exemple, et d'expérimenter avec différentes valeurs à partir de là.
OriginalL'auteur skaffman
C'est de mémoire parce qu'il détiennent toutes les transactions en mémoire et seulement l'envoyer à la base de données lorsque vous appelez
executeBatch
.Si vous n'en avez pas besoin pour être atomique et que vous souhaitez obtenir de meilleures performances, vous pouvez garder un compteur et d'appel
executeBatch
chaque n nombre d'enregistrements.La valeur est à vous, vous devez tester les performances de votre application pour obtenir la meilleure valeur pour que vous le souhaitez pour le commerce entre la mémoire et les performances.
OriginalL'auteur DJ.