请大家帮我定位这个OutOfMemoryError的问题。是数据库?还是连接池?抑或是Java ?

zhousm6 2005-11-18 02:43:27
现在有一个画面做文件上传,将上传的文件写入到数据库的操作。
系统是:linux。
Web+APP:apche + tomcat
数据库:postgreSql
概述:上传文件大小在20M左右,数据大概在12万条左右。已经将tomcat里面文件上传时缓冲池设为最大8192。以前在另外一台linux服务器上也出现过这个问题,后来发现是因为做DB插入的时候用批处理将12万条数据一次处理出错,然后作了修改,每一万条数据做一次批处理操作,能够正常登录。
但是在现在的这台服务器上又出现了OutOfMemoryError的错误(减小到每一千条数据作一次批处理都不行)。通过log跟到做批处理插入的时候就坐不下去了。但是现在这台机器的postgreSql配置跟原来那台服务器是一样的。tomcat的配置也是一样的。不同的是现在这台机器是用公网IP地址来访问的,原来那台服务器是私网。

问题分析:
首先我觉得这个OutOfMemoryError不是tomcat内存不够的原因,因为已经全部把文件内容读到内存里,准备做数据库操作了。有可能是数据库连接池或者数据库本身缓冲池的原因。但到底是哪一个的原因不知道怎么查。另外,两台服务器的数据库,tomcat的配置都是一样的,为什么一个正常,一个不正常呢?

另外有一点儿就是不知道跟他们的ip地址有没有关系。在其他机器上使用客户端工具连接现在这台服务器的数据库的时候,过一段时间就会timeout,需要重新连接。但连接能够正常登录的那台服务器则没有timeout。难道是网络设定的问题?但网络设定跟OutOfMemoryError又有什么关系呢?

不知道大家有什么想法?
...全文
227 13 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
WalkSing 2005-11-19
  • 打赏
  • 举报
回复
没细看。别的先不说。
首先你的思路就有问题。事实上如果上传文件超过了5m.就要考虑换一种思路来解决问题了。

1 有必要是否一定要将file 放入 database ?
2 如果确实必要 那就写一个ftp断点续传吧。

by the way

给大家介绍一个真正的网络电话软件(非广告)
不明白电脑竟然可以拨打电话,也许
你用过Teltel,Skype但是感觉都不尽
如人意,现在更好的免费软件来了!!
一定让你称心如意!(最新消息:telt
el已经关闭了国际线路,skype除了少
数试行地区以外其它地方都关闭了,而
本软件无任何限制) 中国铁通委托上海
枫叶网络科技有限公司试运行免费网络
电话redvip,注册就送5元话费, 拨打
国内一律0.15元/分钟,可拨打35分钟,
保证一次打通,每次通话时间无限制,
可通过推荐好友方式积累话费,无限制
累积,只是需要通过手机接收注册码(是
不是心里有点打鼓了,呵呵)放心吧,
这已经过广大用户证实,公认确实是免费的
铁通不会这点信誉都没有吧),大家可以
先下载再安装帐户在软件上注册
软件下载地址:http://update.redvip.net/RedVIP.exe
注册时请用vip介绍人推荐号:91136084(否则不能赠送话费)
铁通实力强大,试运行用户少速度极快!现在抢先注册吧!
vip 1、一次打通 2、每次通话时间无限制 3、可以发短信
4、可以设置呼叫转移
5、对拨叫用户关机,无信号,号码错误都有提示,和普通电话一样。
官方网站
http://www.redvip.net/default.htm

注:

0 一定要填入介绍人推荐号:91136084(否则不能赠送话费)
1 必须移动卡才可以(目前只开通移动)
2 安装顺序 dotnetfx.exe langpack.exe setup.exe
3 注册时要要注意保管好自己的密码防止别人被倒打你的电话
4 注册成功后要记住自己的ID,密码
5 打固定电话 前加区号 ,手机前要加 0
6 经过我测试资费情况 国内长途 .015 市话座机:0.15 市话移动(我的动感地带):0.13 发短信:0.10 网络vip:0.0

虽然用手机注册,只是获取一个验证码;不扣费

大家在安装过程有问题 可以加我qq 150939 远程协助安装
我的redvip:91136084
我测试过 真的可以 注册后 可以通过91136084号码来跟我的通话:)

本站
http://webcn.isme.net
msn:walksing@hotmail.com
qq:150939
email:walksing@56.com

wxw0342 2005-11-18
  • 打赏
  • 举报
回复
帮顶
zhousm6 2005-11-18
  • 打赏
  • 举报
回复
恩,我也看到过很多地方说增大JVM的内存。不过因为不确定是哪个内存不够的原因,所以没试着增大一下,先增大一下看看吧。
farmer0512 2005-11-18
  • 打赏
  • 举报
回复
你的tomcat设了JVM大小了吗?有可能真的是JVM的内存耗尽了。你试着通过更改tomcat的JAVA_OPTS设置增加JVM的大小看看。tomcat默认的JVM大小是128MB的,你可以增加到512MB看看还会出现OutOfMemoryError吗?。

windows: %TOMCAT_HOME%/bin/catalina.bat
set JAVA_OPTS=-Xms512m -Xmx512m

linux: %TOMCAT_HOME%/bin/catalina.sh
JAVA_OPTS=-Xms512m -Xmx512m
想喝咖啡的貓 2005-11-18
  • 打赏
  • 举报
回复
此贴内容有必要学习, 帮你项...
zhousm6 2005-11-18
  • 打赏
  • 举报
回复
显示outOfMemeory不是在log里面,log里面走到登录执行之前的那句话后,后面什么都没有。
outOfMemory是在画面上出现的。
zhousm6 2005-11-18
  • 打赏
  • 举报
回复
farmer0512(遡风而立者)兄弟谢谢你关注我的这个问题,希望大家一起探讨。
我的log已经出去这个循环了,在
//登录
log.debug("begin to execute....size:" + jsyList.size());
insPstmt.executeBatch();
log.debug("execute finished");
这三句话中,第一句log出来了,最后一句log一直没有出来,所以我想是登录数据库的时候的问题。
farmer0512 2005-11-18
  • 打赏
  • 举报
回复
不好意思弄错了
for (Iterator it = jsyList.iterator(); it.hasNext();) {
// 这是个死循环。除非你的jsyList只有1条记录或者为空
这个不是死循环
你的log显示到哪里就出现Out of Memory?是到这个循环的时候吗?
farmer0512 2005-11-18
  • 打赏
  • 举报
回复
其实你把List导成Iterator使用也会占用近似两倍的内存消耗。
你可以通过List.get(int index)方法直接从List中获取JsymstInfo对象,这样可以去掉一个Iterator应该可以减少内存的消耗
farmer0512 2005-11-18
  • 打赏
  • 举报
回复
for (Iterator it = jsyList.iterator(); it.hasNext();) {
// 这是个死循环。除非你的jsyList只有1条记录或者为空
应该改为
Iterator it = jsyList.iterator();
while(it.hasNext()){

zhousm6 2005-11-18
  • 打赏
  • 举报
回复
DAO中批量数据的插入

PreparedStatement insPstmt = null;
int rt = 0;

//sql文
StringBuffer insSql = new StringBuffer();
insSql.append(" INSERT INTO jsy_mst (" +
" jsycod, " +
" pstbng," +
" jsy001," +
" jsy002," +
" tkystrymd," +
" datetydte," +
" datetyttscod," +
" datetypgmcod)" +
" VALUES(?, ?, ?, ?, TO_DATE(?, 'YYYY/MM/DD'), now(), ?, ?)");

log.debug(insSql.toString());

try {
insPstmt = conn.prepareStatement(insSql.toString());
//SQL文参数设置
for (Iterator it = jsyList.iterator(); it.hasNext();) {

JsymstInfo info = (JsymstInfo) it.next();

int i = 1;

//
insPstmt.setString(i++, info.getJsycod());
insPstmt.setString(i++, info.getPstbng());
insPstmt.setString(i++, info.getJsy001());
insPstmt.setString(i++, info.getJsy002());
insPstmt.setString(i++, newLastStrYMD);
insPstmt.setString(i++, rysnoo);
insPstmt.setString(i++, pgmId);
insPstmt.addBatch();
}

//登录
log.debug("begin to execute....size:" + jsyList.size());
insPstmt.executeBatch();
log.debug("execute finished");

外部控制一次批量数据量
conn = ConnectionMgr.getConnection();

ETC2100_00DAO dao = new ETC2100_00DAO();

// 最新数据登录
// 每一万件登录一次。(OutOfMemoryError防止)
for (int i = 1; ; i++) {

List list = null;
boolean isBreak = false;

int cnt = 10000;
if (i * cnt >= upList.size()) {

list = upList.subList((i-1) * cnt, upList.size());
isBreak = true;

} else {

list = upList.subList((i-1) * cnt, i * cnt);
}

dao.batchInsertData(list, newStrYMD, info.getRysnoo(), pgmId, conn);

if (isBreak) {
break;
}
}

// commit
ConnectionMgr.commitConnection(conn);

这是我的程序。connection都是统一取得,释放的。
chatboycsdn 2005-11-18
  • 打赏
  • 举报
回复
批量操作时,如果用addBatch(),一次批量数据量太大,会出现Out of Memory的错误,解决方法就是以1W或2W条做一次execute(),但不commit,最后再commit
farmer0512 2005-11-18
  • 打赏
  • 举报
回复
你做批量插入是怎么实现的?麻烦把代码贴出来看看好吗?

67,550

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧