你好,java 向数据库添加大量数据时内存溢出 在不改变内存的情况下如何解...
发布网友
发布时间:2022-04-23 06:43
我来回答
共8个回答
懂视网
时间:2022-04-09 00:54
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
public class DBconn {
int bufferSize=20*1024*1024;
ArrayList<String> column3string=new ArrayList<String>();
ArrayList<String> column13string=new ArrayList<String>();
ArrayList<String> test2col1 = new ArrayList<String>();
ArrayList<Integer> test2col2 = new ArrayList<Integer>();
ArrayList<String> test2col3 = new ArrayList<String>();
String driver = "com.mysql.jdbc.Driver";
static String dbName="test";
static String password="6983124ACD";
static String userName="root";
static String url="jdbc:mysql://localhost:3306/" + dbName;
static String sql= "select * from workinfo";
Connection conn=null;
public static Connection getConnection() {
String encoding = "utf-8";
Connection conn = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn=DriverManager.getConnection(url,userName,password);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return conn;
}
public void readFile(String filename) throws FileNotFoundException{
File file = new File(filename);
if (file.isFile() && file.exists()) {
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(file));
InputStreamReader inputStreamReader = new InputStreamReader(bufferedInputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader, bufferSize);
String lineTXT = null;
PreparedStatement pstmt = null;
Connection conn = getConnection();
//String sql = "insert into workinfo(column3,column13) values(1,2)(2,3)(4,5)";
String sql = "insert into workinfo(column3,column13) values(?,?)";
try {
while((lineTXT=bufferedReader.readLine())!=null){
String[] temp = null;
temp = lineTXT.split(" ");
int count = 0;// 计数器
pstmt = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
conn.setAutoCommit(false);// 设置数据手动提交,自己管理事务
pstmt.setString(1, temp[0]);
pstmt.setString(2, temp[0]);
pstmt.addBatch();// 用PreparedStatement的批量处理
if (count % 2000 == 0) {// 当增加了500个批处理的时候再提交
pstmt.executeBatch();// 执行批处理
}
}
conn.commit();
pstmt.close();
conn.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void show(){
System.out.println("This is string:");
for (int i = 0; i < column3string.size(); i++) {
System.out.println(column3string.get(i));
}
System.out.println("This is integer:");
for (int i = 0; i < column13string.size(); i++) {
System.out.println(column13string.get(i));
}
}
public static void main(String[] args) throws FileNotFoundException{
DBconn test=new DBconn();
long timeTsetStart =System.currentTimeMillis();//记录时间
test.readFile("D:\java\Work_Test\ddd.dat");
System.out.println("数据插入成功!");
long timeTestEnd = System.currentTimeMillis();// 记录结束时间
long time = timeTestEnd - timeTsetStart;
long secondTime = time / 1000;
System.out.println("解析时间::" + secondTime + " seconds");
}
}
结果为Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
主要是while((lineTXT=bufferedReader.readLine())!=null){
String[] temp = null;
temp = lineTXT.split(" ");
int count = 0;// 计数器
pstmt = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
conn.setAutoCommit(false);
pstmt.setString(1, temp[0]);
pstmt.setString(2, temp[1]);
pstmt.addBatch();有问题。
java读取文本,插到mysql表中,出现问题。内存溢出。
标签:mysql java
热心网友
时间:2022-04-08 22:02
比如想将一个1000W数据的数据库表,导出到文件;此时,你要么进行分页,oracle当然用三层包装即可,mysql用limit,不过分页每次都会新的查询,而且随着翻页,会越来越慢,其实我们想拿到一个句柄,然后向下游动,编译一部分数据(如10000行)将写文件一次(写文件细节不多说了,这个是最基本的),需要注意的时候每次buffer的数据,在用outputstream写入的时候,最好flush一下,将缓冲区清空下;接下来,执行一个没有where条件的SQL,会不会将内存撑爆?是的,这个问题我们值得去思考下,通过API发现可以对SQL进行一些操作,例如,通过:PreparedStatement statement = connection.prepareStatement(sql),这是默认得到的预编译,还可以通过设置:PreparedStatement statement = connection.prepareStatement(sql , ResultSet.TYPE_FORWARD_ONLY , ResultSet.CONCUR_READ_ONLY);
来设置游标的方式,以至于游标不是将数据直接cache到本地内存,然后通过设置statement.setFetchSize(200);设置游标每次遍历的大小;OK,这个其实我用过,oracle用了和没用没区别,因为oracle的jdbc API默认就是不会将数据cache到java的内存中的,而mysql里头设置根本无效,我上面说了一堆废话,呵呵,我只是想说,java提供的标准API也未必有效,很多时候要看厂商的实现机制,还有这个设置是很多网上说有效的,但是这纯属抄袭;对于oracle上面说了不用关心,他本身就不是cache到内存,所以java内存不会导致什么问题,如果是mysql,首先必须使用5以上的版本,然后在连接参数上加上useCursorFetch=true这个参数,至于游标大小可以通过连接参数上加上:defaultFetchSize=1000来设置,例如:
jdbc:mysql://xxx.xxx.xxx.xxx:3306/abc?zeroDateTimeBehavior=convertToNull&useCursorFetch=true&defaultFetchSize=1000
上次被这个问题纠结了很久(mysql的数据老导致程序内存膨胀,并行2个直接系统就宕了),还去看了很多源码才发现奇迹竟然在这里,最后经过mysql文档的确认,然后进行测试,并行多个,而且数据量都是500W以上的,都不会导致内存膨胀,GC一切正常,这个问题终于完结了。
参考资料:xieyuoo_blog
热心网友
时间:2022-04-08 23:20
2万条数据加载到内存中会出现内存溢出?有点假啊。。。你先试一下不插数据库会不会溢出,如果没有,解决办法:批量插入数据库,2000条一批吧,应该没问题。我当时20多万数据,耗时不到2秒。
热心网友
时间:2022-04-09 00:54
分批次添加啊...你读取表的时候 是一条条读取的吧 这里应该用到循环了
你在循环1000次的时候或者100次的时候 提交一次
热心网友
时间:2022-04-09 02:46
20,000个数据将被加载到内存中的内存溢出?有点假啊。 。 。尽量不要插在数据库中会溢出,如果没有量的解决方案:插入到数据库中,2000年的一批应该是没有问题的。我是20多万数据,消耗小于2秒。
热心网友
时间:2022-04-09 04:54
批量插入,当累积到一定量的数据时先刷新到数据库,然后再循环
热心网友
时间:2022-04-09 07:18
读入使用Buffer
存库用batch update
热心网友
时间:2022-04-09 10:00
一次加载少部分数据追问??? 我是从excel中读出的数据 有2W条 是在几十条之后提交一次嘛?还是如何具体讲解下??
java 向数据库添加大量数据时内存溢出 在不改变内存的情况下如何...
来设置游标的方式,以至于游标不是将数据直接cache到本地内存,然后通过设置statement.setFetchSize(200);设置游标每次遍历的大小;OK,这个其实我用过,oracle用了和没用没区别,因为oracle的jdbc API默认就是不会将数据cache到java的内存中的,而mysql里头设置根本无效,我上面说了一堆废话,呵呵,我只是...
java 程序的内存溢出问题如何解决?
Java程序的内存溢出问题可以通过以下几种方式来解决:1. 增加JVM堆内存大小:可以通过在启动JVM时设置-Xmx和-Xms参数来调整堆内存的大小。例如,"-Xms256m -Xmx1024m"表示最小堆内存为256MB,最大堆内存为1024MB。2. 优化代码:检查代码中是否存在内存泄漏或者不必要的大对象创建。例如,使用完的大对...
代码内存溢出怎么解决
检查对数据库查询中,是否有一次获得全部数据的查询。一般来说,如果一次取十万条记录到内存,就可能引起内存溢出。这个问题比较隐蔽,在上线前,数据库中数据较少,不容易出问题,上线后,数据库中数据多了,一次查询就有可能引起内存溢出。因此对于数据库查询尽量采用分页的方式查询。? 检查List、MAP等 *** 对象是否有使用...
读取大量数据时数据时内存溢出怎样分批读取该怎么处理
这是默认得到的预编译,还可以通过设置: PreparedStatementstatement=connection.prepareStatement(sql,ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_READ_ONLY); 来设置游标的方式,以至于游标不是将数据直接cache到本地内存,然后通过设置statement.setFetchSize(200);设置游标每次遍历...
sqlite插入一万多条数据会报内存溢出 该怎么解决
如果是java层崩了,注意不要一次性加载太多的数据到内存,并且不在使用的数据要彻底放弃引用关系。java虽然是自动回收,回收的原则就是一个对象不再被持有,即引用计数为零。如果数据太大,可考虑临时文件。如果是mysql崩了,首先增加配置缓存。一般来说mysql是不容易崩的,特别是插入操作的时候。查询的...
Java内存溢出的解决方案都有哪些
内存溢出可能是以下原因:内存中加载的数据量过于庞大,如一次从数据库取出过多数据;调用接口超时且超时等待时间设置过长;集合类中有对对象的引用,使用完后未清空,使得JVM不能回收;代码中存在死循环或循环产生过多重复的对象实体;启动参数内存值设定的过小;那么针对的结局方案:优化数据库查询语句,...
解决java读取大文件内存溢出问题,如何在不
3、Apache Commons IO流同样也可以使用Commons IO库实现,利用该库提供的自定义LineIterator:由于整个文件不是全部存放在内存中,这也就导致相当保守的内存消耗:(大约消耗了150MB内存)4、结论这篇短文介绍了如何在不重复读取与不耗尽内存的情况下处理大文件——这为大文件的处理提供了一个有用的解决办法...
java面试题:如何解决内存溢出
3.Java中的内存溢出大都是因为栈中的变量太多了。其实内存有的是。建议不用的尽量设成null以便回收,多用局部变量,少用成员变量。1),变量所包含的对象体积较大,占用内存较多。2),变量所包含的对象生命周期较长。3),变量所包含的对象数据稳定。4),该类的对象实例有对该变量所包含的对象的...
Java中的内存泄露、内存溢出与栈溢出
内存溢出是指程序运行时申请的内存超过了系统可分配的内存资源。这通常由于大量内存泄漏、对象创建过多或内存分配不当引起。内存溢出会导致程序异常终止或性能严重下降。解决方案涉及优化内存使用,及时释放资源,增加系统内存,或使用内存检测工具辅助分析与修正。栈溢出则是程序在执行过程中,递归调用或方法嵌套...
内存溢出的解决方法
内存溢出是指应用系统中存在无法回收的内存或使用的内存过多,最终使得程序运行要用到的内存大于虚拟机能提供的最大内存。内存中加载的数据量过于庞大,如一次从数据库取出过多数据;集合类中有对对象的引用,使用完后未清空,使得JVM不能回收;代码中存在死循环或循环产生过多重复的对象实体;使用的第...