代码,向学生表中添加数据:
package mypackage;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
//测试
public class MyJava {
public static void main(String[] args) throws ClassNotFoundException, SQLException, InterruptedException {
// 加载数据库驱动器,前提是导入了这个jar包
Class.forName("com.mysql.cj.jdbc.Driver");
String url="jdbc:mysql://localhost:3306/test1" +
"?useUnicode=true&characterEncoding=utf8&" +
"useSSL=true&serverTimezone=UTC";
String username="root";
String password="root";
// 建立连接
Connection connection = DriverManager.getConnection(url, username, password);
String sql="insert into students (id,tall) values(?,?)";
// 执行语句,但此时没有真正的执行,给了参数后才真正执行
PreparedStatement preparedStatement = connection.prepareStatement(sql);
System.out.println("暂停20秒,调出jconsole工具,用于观察内存情况");
Thread.sleep(20000);
// 2千万次添加数据,这个程序中900万次就会出现堆内存溢出情况
for (int i=1;i<=20000000;i++){
preparedStatement.setInt(1,i);
preparedStatement.setInt(2,i);
System.out.println(i);//计算循环次数
preparedStatement.addBatch();
}
// 执行批处理
preparedStatement.executeBatch();
// 释放资源
preparedStatement.close();
connection.close();
}
}
简单理解,因为不断的将数据加入到批处理对象中,又不执行,也不释放,就造成了内存溢出。
更改代码:
package mypackage;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
//测试
public class MyJava {
public static void main(String[] args) throws ClassNotFoundException, SQLException, InterruptedException {
// 加载数据库驱动器,前提是导入了这个jar包
Class.forName("com.mysql.cj.jdbc.Driver");
String url="jdbc:mysql://localhost:3306/test1" +
"?useUnicode=true&characterEncoding=utf8&" +
"useSSL=true&serverTimezone=UTC";
String username="root";
String password="root";
// 建立连接
Connection connection = DriverManager.getConnection(url, username, password);
String sql="insert into students (id,tall) values(?,?)";
// 执行语句,但此时没有真正的执行,给了参数后才真正执行
PreparedStatement preparedStatement = connection.prepareStatement(sql);
System.out.println("暂停20秒,调出jconsole工具,用于观察内存情况");
Thread.sleep(20000);
// 2千万次添加数据,这个程序中900万次就会出现堆内存溢出情况
for (int i=1;i<=20000000;i++){
preparedStatement.setInt(1,i);
preparedStatement.setInt(2,i);
System.out.println(i);//计算循环次数
preparedStatement.addBatch();
// 每隔10万次,批量执行一次,然后清空clearBatch
// 如果不这样做,在这个程序中900万次就会出现堆内存溢出情况
if (i%100000==0){
preparedStatement.executeBatch();
preparedStatement.clearBatch();
}
}
// 执行剩余批处理
preparedStatement.executeBatch();
// 释放资源
preparedStatement.close();
connection.close();
}
}
具体的多少次会造成内存溢出,根据不同的处理程序,机器性能决定,每隔多少次进行一次批处理执行,少于会造成内存溢出的次数即可,但是最好不要接近这个值。因为越到后期,随着次数的增加,速度越慢。