[b]
---------Consumer myList.size():3
Consumer: 2
---------Consumer myList.size():2
Consumer: 1
---------Consumer myList.size():1
Consumer: 0
myList warning: it's empty!
star:234000
end:236000
Exception in thread "Thread-3" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:2882)
at java.lang.StringCoding.trim(StringCoding.java:71)
at java.lang.StringCoding.access$100(StringCoding.java:34)
at java.lang.StringCoding$StringDecoder.decode(StringCoding.java:147)
at java.lang.StringCoding.decode(StringCoding.java:169)
at java.lang.String.(String.java:444)
at com.mysql.jdbc.ResultSetRow.getString(ResultSetRow.java:760)
at com.mysql.jdbc.BufferRow.getString(BufferRow.java:538)
at com.mysql.jdbc.ResultSetImpl.getStringInternal(ResultSetImpl.java:5557)
at com.mysql.jdbc.ResultSetImpl.getString(ResultSetImpl.java:5434)
at com.mysql.jdbc.ResultSetImpl.getStringForClob(ResultSetImpl.java:5485)
at com.mysql.jdbc.ResultSetImpl.getObject(ResultSetImpl.java:4821)
at cn.lake.databases.MysqlClass.executeQuery(MysqlClass.java:464)
at cn.lake.start.DoStart$Producer.run(DoStart.java:97)[/b]
原码部分:
package cn.lake.start;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import cn.lake.cache.DataProperties;
import cn.lake.cache.Property;
import cn.lake.databases.MysqlClass;
import cn.lake.databases.MysqlConnetionPool;
import cn.lake.util.MSTMConfig;
public class DoStart {
private LinkedList myList = new LinkedList();
private static LinkedList propertyList = new LinkedList();
private int MAX = 100;
private final Lock lock = new ReentrantLock();
private final Condition full = lock.newCondition();
private final Condition empty = lock.newCondition();
public DoStart() {
}
public void start() {
new Producer().start();
new Consumer().start();
}
public static void main(String[] args) throws Exception {
DoStart s2 = new DoStart();
addPaginateion();
s2.start();
}
private static void addPaginateion() {
MSTMConfig mconfig = new MSTMConfig();
MysqlClass mysqlConnect;
MysqlConnetionPool mysqlConnectionPool = new MysqlConnetionPool(mconfig.myServerName, mconfig.myDbName, mconfig.myLoginName,mconfig.myLoginPwd);
List rs = null;
String sql = "SELECT COUNT(*) as exp From tb_paid_resume_info";
mysqlConnect = new MysqlClass(mysqlConnectionPool);
rs = mysqlConnect.executeQuery(sql);
int count = Integer.parseInt(((Map) rs.get(0)).get("exp")
.toString());
// 分页数
int pagination = 0;
int paginationSpare = count % mconfig.myReadCount;
System.out.println("数据库总数据量为:" + count);
System.out.println("分页大小为:" + mconfig.myReadCount);
if (paginationSpare == 0) {
pagination = count / mconfig.myReadCount;
} else {
pagination = count / mconfig.myReadCount + 1;
}
Property property = null;
DataProperties dproperty = null;
for (int i = 1; i <= pagination; i++) {
int endPoint = i * mconfig.myReadCount;
if (i == 1) {
property = new Property(0, endPoint);
} else {
if (i == pagination) {
property = new Property((i - 1)* mconfig.myReadCount, count);
} else {
property = new Property((i - 1)* mconfig.myReadCount, endPoint);
}
}
propertyList.add(property);
}
}
class Producer extends Thread {
public void run() {
while (true) {
lock.lock();
try {
System.out.println("-------------Producer myList.size():"+myList.size());
while (myList.size() > MAX) {
System.out.println("warning: it's full!");
full.await();
}
if(propertyList.size()>0){
List resumeRs= null;
MSTMConfig mconfig = new MSTMConfig();
MysqlClass mysqlConnect;
MysqlConnetionPool mysqlConnectionPool = new MysqlConnetionPool(mconfig.myServerName, mconfig.myDbName, mconfig.myLoginName,mconfig.myLoginPwd);
int star= propertyList.getLast().getStart();
int end= propertyList.getLast().getEnd();
System.out.println("star:"+star);
System.out.println("end:"+end);
String resumeSql = "SELECT * From tb_paid_resume_info limit "+star+","+end;
mysqlConnect = new MysqlClass(mysqlConnectionPool);
resumeRs = mysqlConnect.executeQuery(resumeSql);
for(int r=0;r<resumeRs.size();r++){
if (myList.add(r)) {
System.out.println("Producer: " + r);
}
}
empty.signal();
propertyList.removeLast();
System.out.println("==================propertyList.size():"+propertyList.size());
}
} catch (InterruptedException ie) {
System.out.println("producer is interrupted!");
} finally {
lock.unlock();
}
}
}
}
class Consumer extends Thread {
public void run() {
while (true) {
lock.lock();
try {
while (myList.size() ==0) {
System.out.println("myList warning: it's empty!");
empty.await();
}
System.out.println("---------Consumer myList.size():"+myList.size());
Object o = myList.removeLast();
System.out.println("Consumer: " + o);
full.signal();
} catch (InterruptedException ie) {
System.out.println("consumer is interrupted!");
} finally {
lock.unlock();
}
}
}
}
}
===数据库总数据量为:321323
分页大小为:2000
请各位帮看看是什么问题,老OOM,请到10万时就OOM
/**
* 执行查询语句
*
* @param sql
* @return
*/
public List executeQuery(String sql) {
ConnectionWrapper connectionWrapper = this.getConnectionWrapper();
Statement stmt = this.getStmt(connectionWrapper.connection);
List<Map> list = new ArrayList<Map>();
int mysqlErrorTimes = 1;
while (mysqlErrorTimes > 0 && mysqlErrorTimes <= 10) {
try {
ResultSet rs = null;
rs = (ResultSet) stmt.executeQuery(sql);
if (rs != null) {
ResultSetMetaData rsmd = (ResultSetMetaData) rs
.getMetaData();
while (rs.next()) {
Map<Object, Object> map = new HashMap<Object, Object>();
for (int i = 1; i <= rsmd.getColumnCount(); i++) {
map.put(rsmd.getColumnName(i), rs.getObject(i));
}
list.add(map);
}
}
rs.close();
rs = null;
mysqlErrorTimes = 0;
} catch (Exception e) {
connectionWrapper = isError(connectionWrapper, stmt, sql, e);
stmt = this.getStmt(connectionWrapper.connection);
mysqlErrorTimes++;
}
}
this.release(connectionWrapper.connection, stmt);
return list;
}
}
[b]问题补充:[/b]
首先,謝謝大家支持;
就是使用-Xmx参数配置你JVM执行程序时的最大使用内存。
二、如果执行以上命令仍内存溢出的话,仔细检查你的批量处理代码,修正其中的问题。
對JVM增大內存我試過,當內存增大到1G時,可以跑到10萬的量,然后又OOM,而批量處理,不好意思,這里我還沒有做批量的處理,只是打印出來而已,并沒有做插入動作,所以這個不需要考慮;
數據庫,我每次查詢都有一個
mysqlErrorTimes++;
}
}
[b]this.release(connectionWrapper.connection, stmt); [/b]
return list;
}
釋放和關閉動作,所以我才奇怪!