[code="java"]
public class TestThread extends Thread{
public void run(){
JDBCConnector conn = new JDBCConnector();
conn.creatConnection();
StringBuffer ids;
ResultSet rs;
//其他String变量
while(true){
try{
rs = null;
ids = new StringBuffer();
rs = conn.executeQuery("select id from test1 where status=0");
while(rs.next()){
ids.append(rs.getInt("id"));
ids.append(",");
}
//1、简单的业务逻辑处理,会用到其他String变量
//2、业务逻辑处理完成后,根据ids将status更新为1
Thread.sleep(1000);
}catch (Exception e) {
e.printStackTrace();
}
}
}
}
[/code]
以上这个线程,运行几天后,tomcat会报[b]“GC overhead limit exceeded”[/b],d代码上是否有什么不合理的地方。
可能是因为rs没有关闭。
[code="java"]if(!rs.isClosed()){
rs.close();
}
Thread.sleep(1000); [/code]
jvm gc行为中超过98%以上的时间去释放小于2%的堆空间时会报这个错误。
处理方法:
1. 在jvm启动参数中添加 "-XX:-UseGCOverheadLimit",该参数在JDK6中默认启用("-XX:+UseGCOverheadLimit")。
调整后的生产环境中使用的参数为:
JAVA_OPTS='-Xms512m -Xmx4096m -XX:MaxPermSize=128m -XX:-UseGCOverheadLimit -XX:+UseConcMarkSweepGC'
2. 检查是否有使用了大量内存的代码或死循环
jstat监控gc的命令格式为:
jstat -gcutil [-t] [-h] [ []]
vmid为JVM进程id,可以用ps -ef 或 jps -lv命令查找。
以下命令为每1秒钟输出一次gc状态,共输入5次
楼主,你检查一下,是不是你的数据比较大,全append到stringbuffer,占用的内存太大了啊。而且你的stringbuffer append完后貌似没哟序列化或者清空,线程每次执行都要重新实例对象,导致GC要不停的去回收。完善一下代码,在试试
jconsole开起来看看内存回收情况