public class M_index extends Model
{    @Override
    protected void executing(HttpServletRequest request, HttpServletResponse response, ModelConfig mc) throws JasperException 
    {
        Pagination p = ArticleDao.list(1, 4);
        request.setAttribute("articleList", p.absolutePage());
        path = mc.get("to_index");
    }
    
}
ArticleDao.list(1, 4);public static Pagination list(int absolutePage,int pageSize)
    {
        Pagination p = new P_article_all();
        p.setPageSize(pageSize);
        p.setAbsolutePage(absolutePage);
        return p;
    }P_article_all类public class P_article_all extends Pagination{    @Override
    public Iterator absolutePage() 
    {
        ArrayList list = new ArrayList();;
        String sqlcmd = "SELECT * FROM jh_article ORDER BY wtime DESC LIMIT "+(this.getAbsolutePage()-1)*this.getPageSize()+","+this.getPageSize();
        ResultSet rs = Select.select(sqlcmd, "");
        try {
           ArticleDao.addDataToList(rs, list);
        } catch (SQLException ex) {
            Log.exception(Log.getLogger("database"), ex, Level.WARNING);
        }finally
        {
            Select.closeResultSet(rs);
        }
        
        
        return list.iterator();
    }    @Override
    public int getRecordTotal() 
    {
        if(recordTotal == 0)
        {
            int count = 0;
            ResultSet rs = Select.select("SELECT count(*) FROM jh_article", "");            try {
                if (rs.next()) {
                    count = rs.getInt(1);
                }
            } catch (SQLException ex) {
                Log.exception(Log.getLogger("database"), ex, Level.WARNING);
            }finally
            {
                Select.closeResultSet(rs);
            }
            recordTotal = count;
        }
        return recordTotal;
        
    }}
大家看下,我有没有内存泄露,我实际测试中发现内存泄露,但是我找不出来,帮忙下,如果分数不够,可以在加。可以加到200分

解决方案 »

  1.   

    好像没看到数据库关闭的地方,是不是连接池没有释放如果是java的代码泄露,一般指长引用 而导致对象不能释放,可以用jrun,jprobe,jprofile查查
      

  2.   

    这程序不会报错,数据库有关,用的是连接池,这程序会顺利执行,就是这个程序跑很长时间(1天左右)300多MB的内存会被吃光,接着TOMCAT就抱JAVA SPACE HEAP
      

  3.   

    有可能是你的LIST中存放的数据超过内存导致.(具体要看你的异常日志)
      

  4.   

    怎么可能了,LIST里面不超过30条纪录,
      

  5.   

    用的是什么服务,tomcat  OR  weblogic??
      

  6.   

    把Select.closeResultSet(rs);这个方法的代码贴出来我猜你是只关了rs没关Statement和Connection吧
      

  7.   

    ResultSet, Statement, Connection最好要及时关闭。不能完全依赖GC
      

  8.   

    这就是那个Select类, Select.closeResultSet(rs); 也在这里面,Connection对象 是由连接池回收的public class Select {
        /**
         * 查询SQL
         * 例: SELECT * FROM WHERE id=?  value则对应这个id ,多个value用","隔开
         * 没有value,则用""来标识
         * 
         * @param sql
         * @param value
         * @return ResultSet 
         * @throws java.sql.SQLException
         */
        public static ResultSet select(String sql, String value)
        {
            if(sql == null || value == null)
            {
                System.out.println("sql : null");
                return null;
            }
            
            String[] values=value.split(",");
            Log.getLogger("database").info(sql);
            ResultSet rs = null;
            Connection conn = null;
            PreparedStatement ps = null;
            try 
            {
                conn = ConnectionPool.getInstance().getConnection();
                ps = conn.prepareStatement(sql);
                
                int count = values.length;
                
                if("".equals(value))
                {
                    count = 0;
                }
                
                for(int i=0;i<count;i++)
                {
                    ps.setObject(i+1, values[i]);
                }
                
                rs = ps.executeQuery();
            } catch (SQLException ex) 
            {
                closePreparedStatement(ps);
                ex.printStackTrace();
                return null;
            }finally
            {
                if(conn !=null)
                {
                    ConnectionPool.getInstance().returnConnection(conn);
                }
            }
            
            return rs;
        }
        
        public static void closePreparedStatement(PreparedStatement ps)
        {
                if(ps!=null)
                {
                    try {
                        ps.close();
                        ps = null;
                        Log.getLogger("database").info("ps:close");
                    } catch (SQLException ex) {
                        Logger.getLogger(Select.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
        }
        
        public static void closeResultSet(ResultSet rs)
        {
            if(rs!=null)
                try 
                {
                    rs.getStatement().close();
                    rs = null;
                    Log.getLogger("database").info("rs:close");
                } catch (SQLException ex) {
                    Logger.getLogger(Select.class.getName()).log(Level.SEVERE, null, ex);
                }
                
        }
    }
      

  9.   

    rs.getStatement().close();关闭statement,也会关闭ResultSet,这是本人证实过的,API里也哟说过
      

  10.   

    现在,通过楼主所帖出来的代码来观察,
    问题,可能出现在两个地方:
    一个地方是Statement没有close掉。
    另一个,就是list在使用完毕后,没有clear操作。
    由于不知道ArticleDao.addDataToList(rs, list);这个静态方法里面,具体的操作内容,所以无法判断是否是list对象引起的。再去看看,有没有什么关于数据的缓存的代码,
    内存被暴掉,有可能是缓存的数据,没有及时删除,
    或者,ResultSet里面的记录过多,而引起的。
      

  11.   


    如果是我们一般说的“Java 内存泄露”,其实就是“分配了很多对象,虽然已经不再使用了,但仍然被持有着(比如保存在某个 Collection 中”,那么,其导致的内存不足出的错误是 OutOfMemoryError,而不是楼主这里说的“JAVA SPACE HEAP”错误。这种 HEAP 之类的错误,往往是通过 JNI 调用 Native code 时内存不足而崩出来的错误。结合楼主提的问题,建议你去检查一下所使用的 JDBC Driver,是否有 Native code 的成分、是否有内存泄露的 BUG。另外,报出 HEAP 错误的那个地方,应该还有其它一些错误信息可供参考。
      

  12.   

    报出 HEAP 错误的那个地方,应该还有其它一些错误信息可供参考。
    这个没有,就单一的java内存溢出,JAVA SPACE HEAP 我用的是MYSQL 的JDBC驱动包,我觉的这个应该是没有问题的,由于不知道ArticleDao.addDataToList(rs, list);这个静态方法里面,具体的操作内容,所以无法判断是否是list对象引起的。 
    这个list是由外面引进去的,内部没有任何调用,只是为了把rs里的内容,用对象形式 附加到list里面,用的是引用传递
      

  13.   

    ResultSet里面的记录过多,而引起的。 纪录不多,最多30条,因为这是分页程序
      

  14.   

    //是不是数据内容太多 一次查询超过了 几千条 看看数据是多少 可能session里面数据太多造成内存不足溢出了。。java是内存溢出吧。。内存泄露。楼下能解释一下  溢出和泄露的关系吗?
      

  15.   

    你的代码很乱,而且编程习惯不是很好,数据库访问最好不要返回结果集,这样造成长期占用数据库连接;而且关闭数据库连接最基本的顺序是先关闭rs,再关闭stmt,最后关闭connection,虽然关闭connection后其他两个也会关闭,但这是良好的编码习惯,代码清晰明了。你在程序中分别关闭,在函数中跳来跳去,很容易出现类似你的问题的现象,而且对阅读代码也造成一定阻碍。你的代码个人认为没有可参考性,所以建议你改变你的编码习惯,按步就班做,你的业务很简单,肯定不会有错。以上属个人意见,如果措辞步当请原谅
      

  16.   

    自己改写一下这个方法,然后看看是否还是泄漏,我觉得可能就是这个方法每次加载的数据在使用之后没有释放掉,或者你自己尝试在载入下一页之前把list清空一下看看。
      

  17.   

    request.setAttribute("articleList", p.absolutePage());
    我记得论坛上谁说过,这样set,会导致占用空间越来越大,试试看在用完之后removeAttribute
      

  18.   

    错误信息到底是什么?能否“原样”帖出来看看?另外,你用的 MySQL Driver 是什么版本的?
      

  19.   

    我前几天也遇到了这个问题,我们用的是oc4j啦,可呢,就把它的虚拟内存的分配给增加了一些,之后就可以啦,其二呢,就是数据库的问题啦,如果你的数据库的记录过多时,再往里插入数据时,也会报同样的内存溢出问题,最后,就是代码问题啦,这也不光是connection的问题,还有session不及时释放啦,死循环啦,异常中的异常啦,这些都是可能发生的!