java 向数据库添加大量数据时内存溢出 在不改变内存的情况下如何解决

java 程序向oracle数据库批量一次插入5000条数据提示我超出虚拟机内存,我改如何处理,并且怎样加快时间,哪个高手指点一下,感激不尽。

比如想将一个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一切正常,这个问题终于完结了。
温馨提示:内容为网友见解,仅供参考
第1个回答  2010-05-18
具体问题具体处理。
你最起码应该说明是哪种数据库
是用JDBC还是ODBC还是hibernate。

一般这种情况都是分批插入。

每个会话插入50条,然后关闭,再重新做一次连接。
然后再插。
或者中间多做几次commit

access的数据库在使用某个版本的驱动时,如果是免费版的,
一次就只能插入50条数据。本回答被提问者采纳
第2个回答  2010-05-18
每20条commit下 100%不会内存溢出
第3个回答  2010-05-31
我也遇到过,你可以每10条执行后,提交一次commit

你好,java 向数据库添加大量数据时内存溢出 在不改变内存的情况下如何解...
需要注意的时候每次buffer的数据,在用outputstream写入的时候,最好flush一下,将缓冲区清空下;接下来,执行一个没有where条件的SQL,会不会将内存撑爆?是的,这个问题我们值得去思考下,通过API发现可以对SQL进行一些操作,例如,通过:PreparedStatement statement = connection.prepareStatement(sql),这...

...向数据库添加大量数据时内存溢出 在不改变内存的情况下如何解决
需要注意的时候每次buffer的数据,在用outputstream写入的时候,最好flush一下,将缓冲区清空下;接下来,执行一个没有where条件的SQL,会不会将内存撑爆?是的,这个问题我们值得去思考下,通过API发现可以对SQL进行一些操作,例如,通过:PreparedStatement statement = connection.prepareStatement(sql),这...

ireport查询数据有80万条,内存溢出怎么解决
第一步,就是修改JVM启动参数,直接增加内存。这一点看上去似乎很简单,但很容易被忽略。JVM默认可以使用的内存为64M,Tomcat默认可以使用的内存为128MB,对于稍复杂一点的系统就会不够用。在某项目中,就因为启动参数使用的默认值,经常报"OutOfMemory"错误。因此,-Xms,-Xmx参数一定不要忘记加。第二...

Java前提下, MySQL数据库,一次性存储大量数据导致内存溢出
如果是java层崩了,注意不要一次性加载太多的数据到内存,并且不在使用的数据要彻底放弃引用关系。java虽然是自动回收,回收的原则就是一个对象不再被持有,即引用计数为零。如果数据太大,可考虑临时文件。如果是mysql崩了,首先增加配置缓存。一般来说mysql是不容易崩的,特别是插入操作的时候。查询的时...

Java内存溢出的解决方案都有哪些
启动参数内存值设定的过小;那么针对的结局方案:优化数据库查询语句,如改成分页查询;调用接口超时时间设置短一些,打印错误日志,修正超时的接口;集合类使用完后设置成null,例:在执行完list之后写上list=null;使用debug逐步查找死循环的代码 将jvm内存的值增大:-Xms1024m -Xmx1024m -XX:MaxNewSize=...

内存溢出的定义和原因 如何解决内存溢出问题
1. 数据加载过多,如从数据库一次性取出大量数据。2. 集合类中存在对对象的引用,使用后未清空,导致JVM无法回收内存。3. 程序中存在死循环或循环生成大量对象。4. 第三方软件存在BUG。5. 启动参数设置不当。解决问题 第一步,调整JVM启动参数,增加可用内存。第二步,检查错误日志,寻找异常或错误。

java面试题:如何解决内存溢出
3.Java中的内存溢出大都是因为栈中的变量太多了。其实内存有的是。建议不用的尽量设成null以便回收,多用局部变量,少用成员变量。1),变量所包含的对象体积较大,占用内存较多。2),变量所包含的对象生命周期较长。3),变量所包含的对象数据稳定。4),该类的对象实例有对该变量所包含的对象的...

在java中上传文件出现内存溢出怎么解决
具体问题具体处理。你最起码应该说明是哪种数据库 是用JDBC还是ODBC还是hibernate。一般这种情况都是分批插入。每个会话插入50条,然后关闭,再重新做一次连接。然后再插。或者中间多做几次commit

Java 内存溢出问题 Caused by: java.lang.OutOfMemoryError_百度知 ...
其实数据没必要一次性的全部查出来,现在你全部查出来你的内存肯定是承受不了 推荐你2种比较实际的解决方案:1.扩充JVM内存设置参数,默认我记得好像是256MB 2.从代码入手,优化你的查询设置,现在你一次性全部查出来肯定不合理,要是数据量小还可以,现在是数据量太大,堆空间肯定崩 ...

java 怎么把5万条数据分批插入数据到mysql,之前插1,2万没事, 多了就...
大量数据插入的时候,可以将数据量分批,每次事务提交一批。例如:con.setAutoCommit(false);\/\/ 更改JDBC事务的默认提交方式 Statement stmt = conn.createStatement();\/\/ 第一批 省略n条 stmt.addBatch("insert into dept values (52,'a','aa')");stmt.addBatch("insert into dept values (53,'...

相似回答