学习记录296@PreparedStatement批处理中堆内存溢出

代码,向学生表中添加数据:

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();
    }
}


在这里插入图片描述
具体的多少次会造成内存溢出,根据不同的处理程序,机器性能决定,每隔多少次进行一次批处理执行,少于会造成内存溢出的次数即可,但是最好不要接近这个值。因为越到后期,随着次数的增加,速度越慢。

猜你喜欢

转载自blog.csdn.net/weixin_44663675/article/details/107443120