小弟第一次发帖,请多多指教。希望大家耐心听我说。由于服务器不在边上,
管理人员说是内存溢出,有一张图片信息
我想我的的jdbc是我自己封装的,会不会有问题。
这里是连接类:
/**
 * 数据源.
 * @time 2012-12-31 09:19:33
 */
package com.DataSource;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;import com.Exceptions.DB_Exception;/**
 * @author Administrator
 * 
 */
public final class DataSource {
    /**
     * . 构造函数.
     */
    private DataSource() {
    }    /**
     * . 静态数据库连接.
     */
    private static Connection conn = null;    /**
     * @return conn.
     * @throws DB_Exception
     *             Exception.
     */
    public static Connection getConnection() throws DB_Exception {
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager
                    .getConnection(
                            "jdbc:mysql://192.168.1.104:3306/itao?characterEncoding=gbk",
                            "qqq", "");
        } catch (ClassNotFoundException e) {
            // 抛异常
            throw new DB_Exception(e);
        } catch (SQLException e) {
            // 抛异常
            throw new DB_Exception(e);
        }
        if (conn == null) {
            throw new DB_Exception("conn为空!!!");
        }
        return conn;
    }    /**
     * @throws DB_Exception
     *             Exception
     */
    public static void close(ResultSet rs, Statement stat, Connection conn)
            throws DB_Exception {
        try {
            if (rs != null)
                rs.close();
        } catch (SQLException e) {
            throw new DB_Exception(e);
        } finally {
            try {
                if (stat != null)
                    stat.close();
            } catch (SQLException e) {
                throw new DB_Exception(e);
            } finally {
                try {
                    if (conn != null)
                        conn.close();
                } catch (SQLException e) {
                    throw new DB_Exception(e);
                }
            }
        }
    }
}还有就是小弟用jrockit内存检测工具(因为服务器上不好装,所以这个工具只装在了本地自己测,可能测得不准),工具指出以下这个类的这个方法67行和75行有问题(看我注释上有标行数)。
这个方法写在dao层里的,方法大致的作用是通过传过来的用户返回一个经过筛选后拼接的集合,用的struts2框架

public List<Task> taskListWithUser(User u) throws DB_Exception, EarnDao_Exception {
        String sb = "";
        String sb2 = "";
        List<Task> taskList = new ArrayList<Task>();
        Connection conn = DataSource.getConnection();//第67行
        //sql1:获得任务对象,赛选条件:①指定的用户ID②任务类型为一个用户只能做一次的类型③此任务已完成
        String stringsql = "select t.* from task t left join users_task ut on t.id=ut.tid where ut.uid=? and t.tasktype=0";
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = conn.prepareStatement(stringsql);
            ps.setInt(1, u.getId());
            rs = ps.executeQuery();//有问题 第75行
            while (rs.next()) {
                Task t = new Task();
                sb += ","+rs.getInt("id");
                //sb.append(","+rs.getInt("id"));
                t.setBeans(rs.getInt("beans"));
                t.setHref(rs.getString("href"));
                t.setId(rs.getInt("id"));
                t.setImgsrc(rs.getString("imgsrc"));
                t.setTaskname(rs.getString("taskname"));
                t.setTaskType(rs.getBoolean("tasktype"));
                t.setVisit(rs.getString("visit"));
                t.setTaskstate("任务已完成");
                t.setHreftype(rs.getString("hreftype"));
                taskList.add(t);
            }
          //sql3:获得对象,赛选条件:①指定用户ID②任务类型:一个用户一天只能做一次③此任务已完成
            String stringsql3 = "select t.* from task t left join users_task ut on t.id=ut.tid where ut.uid=? and t.tasktype=1 and  CURDATE()=date_format(ut.tasktime,'%Y-%m-%d')";
            ps = conn.prepareStatement(stringsql3);
            ps.setInt(1, u.getId());
            rs = ps.executeQuery();
            while (rs.next()) {
                Task t = new Task();
                sb2 += ","+rs.getInt("id");
                //sb2.append(","+rs.getInt("id"));
                t.setBeans(rs.getInt("beans"));
                t.setHref(rs.getString("href"));
                t.setId(rs.getInt("id"));
                t.setImgsrc(rs.getString("imgsrc"));
                t.setTaskname(rs.getString("taskname"));
                t.setTaskType(rs.getBoolean("tasktype"));
                t.setVisit(rs.getString("visit"));
                t.setTaskstate("任务已完成");
                t.setHreftype(rs.getString("hreftype"));
                taskList.add(t);
            }
          //sql2:获得任务对象,赛选条件:①指定的用户ID②任务类型:一个用户只能做一次③此任务未完成
            String stringsql2 = null;
            if("".equals(sb)) {
                stringsql2 = "select * from task where tasktype=0";
            } else {
                stringsql2 = "select * from task where tasktype=0 and id not in (" + sb.substring(1) + ")";
            }
            ps = conn.prepareStatement(stringsql2);
            rs = ps.executeQuery();
            while (rs.next()) {
                Task t = new Task();
                t.setBeans(rs.getInt("beans"));
                t.setHref(rs.getString("href"));
                t.setId(rs.getInt("id"));
                t.setImgsrc(rs.getString("imgsrc"));
                t.setTaskname(rs.getString("taskname"));
                t.setTaskType(rs.getBoolean("tasktype"));
                t.setVisit(rs.getString("visit"));
                t.setTaskstate("任务未完成");
                t.setHreftype(rs.getString("hreftype"));
                taskList.add(t);
            }
          //sql4:获得对象,赛选条件:①指定用户ID②任务类型:一个用户一天只能做一次③此任务未完成
            String stringsql4 = null;
            // String stringsql4 = "select DISTINCT(t.id) as ok,t.* from task t left join users_task ut on t.id=ut.tid where t.tasktype=1 and (ut.uid!=? or ut.uid is null) and (ut.tasktime!=CURDATE() or ut.taskname is null )";
            if("".equals(sb2)) {
                stringsql4 = "select * from task where tasktype=1";
            } else {
                stringsql4 = "select * from task where tasktype=1 and id not in (" + sb2.substring(1) + ")";
            }
            ps = conn.prepareStatement(stringsql4);
            rs = ps.executeQuery();
            while (rs.next()) {
                Task t = new Task();
                t.setBeans(rs.getInt("beans"));
                t.setHref(rs.getString("href"));
                t.setId(rs.getInt("id"));
                t.setImgsrc(rs.getString("imgsrc"));
                t.setTaskname(rs.getString("taskname"));
                t.setTaskType(rs.getBoolean("tasktype"));
                t.setVisit(rs.getString("visit"));
                t.setTaskstate("任务未完成");
                t.setHreftype(rs.getString("hreftype"));
                taskList.add(t);
            }
        } catch (SQLException e) {
            throw new EarnDao_Exception(e);
        } finally {
            DataSource.close(rs, ps, conn);
        }
        return taskList;
    }
jdbc代码内存溢出了嘛

解决方案 »

  1.   

      Task t = new Task();定义的太多了吧,应该写在循环外,这每次都是一个新的对象了。
      

  2.   

    嗯 那我是不是应该改成这样子,可是我有疑问,这样写还是在循环里new的对象呀,每循环一次不还是要分配空间的嘛?
    Task t = null;
                while (rs.next()) {
                    t = new Task();
                    t.setBeans(rs.getInt("beans"));
                    t.setHref(rs.getString("href"));
                    t.setId(rs.getInt("id"));
                    t.setImgsrc(rs.getString("imgsrc"));
                    t.setTaskname(rs.getString("taskname"));
                    t.setTaskType(rs.getBoolean("tasktype"));
                    t.setVisit(rs.getString("visit"));
                    t.setTaskstate("任务未完成");
                    t.setHreftype(rs.getString("hreftype"));
                    taskList.add(t);
                }
      

  3.   

    1楼真心傻了下   这必须得创建这么多对象  这里没得挑剔
    你这代码让我看了想哭   我大致看懂了点   你是需要根据一个用户然后对一个表进行四种不同条件的查询  之后将结果连接到一起是吧  最好想办法使用一条SQL语句将四个查询合并到一起  或者将结果合并到一起也行  Oracle可以合并查询结果   你瞅瞅吧
      

  4.   

     while (rs.next()) {              
       Task t = new Task(); 
    }

    Task t=null
    while (rs.next()) {              
        t = new Task(); 
    }
    区别在哪里呢?呵呵!不明白
      

  5.   

    谢谢,那段代码我也是想了很久才憋出来的,那个项目是我和另一个实习生做。数据库也是我们自己设计,感觉是数据库设计的不够好。所以处理sql语句的时候才会显得那么辣手。。
      

  6.   

    退到重新做这个方法。根据条件用stingbuffer去拼sql语句
      

  7.   

    是不是开了N个CONNECTION导致的,你把DataSource改成单例模式看看。
      

  8.   

    问题多了去了,第一行就是问题!private static Connection conn = null;
      

  9.   

    我在 CSDN 说过不下三十遍了,不要自以为是地把 JDBC 的连接对象:Connection, Statement, ResultSet 弄成成员变量,你竟然还是静态的成员变量!我整理了一下我曾经回复过的帖子,有兴趣的话可以去看一下:Connection 能设置成静态的吗
    http://bbs.csdn.net/topics/350052222#post-351357361第一次用c3p0 请大家帮我分析一下这个日志吧
    http://bbs.csdn.net/topics/360136023#post-370438696JDBC connection 讨论
    http://bbs.csdn.net/topics/360027520#post-361821072jdbc 单例的问题
    http://bbs.csdn.net/topics/340196656#post-342500259KO众多高手的jdbc问题--请谨慎模仿
    http://bbs.csdn.net/topics/330258692#post-340441341并发时出现的 java.sql.SQLException: 关闭的 Resultset: next
    http://bbs.csdn.net/topics/340259805#post-350662127老是连接不到数据库
    http://bbs.csdn.net/topics/350013301#post-350939754tomcat连接池,重复多次调用方法出错: Connection is closed
    http://bbs.csdn.net/topics/300050166#post-300727818用JDBC处理一对一的关系出错,该怎么改
    http://bbs.csdn.net/topics/320020104#post-320280650关于连接池的问题
    http://bbs.csdn.net/topics/290058323#post-250725019还有不计其数的帖子都是这类问题,我就不再一一列出来的。从这些帖子可以看出,个个对 ORM 工具用得非常熟悉,但是对于基础的东西则是非常不了解。不管学什么,只有牢固的根基,才会有枝繁和叶茂,否则只要一有风雨,则会承受不住而倒。