java有没有内存泄漏与N+1问题

来源:互联网 发布:三星手机3g网络设置 编辑:程序博客网 时间:2024/05/29 16:15

(一)java有没有内存泄漏

        在语法上java没有内存泄漏,因为有垃圾收集器。但是在编程的时候,则会引起内存泄漏。比如:写程序时用到了一些资源一定要回收(关闭),就像打开连接池,一定要关闭,否则就在内存中一直打开。打开文件要关闭,不关闭的话,java无法调用本地的资源文件将其关闭。打开文件相当于java调用c,c调用windows的api,c语言需要手动回收内存。

同时注意session.clear()的运用,尤其在不断分页循环的时候。每一页在读取完之后,要清理掉缓存,即使用session.clear(),否则每页的缓存都会存放在内存中,内存就会被沾满,就会会引起内存泄漏。

(二)1+N或者N+1问题(对于关联表多对一或者一对)

     本来所有信息可以一次性查询出来,也就是简单的连表查询,但是Hibernate会首先查询1次得到当前对象,然后当前对象里面的n个关联对象会再次访问数据库n次,这就是1+n问题。

对于hibernate,多对一默认fetchType默认是Eager即(fetch=FetchType.EAGER),会出现N+1问题。

解决方法:

1.延迟加载(fetch=FetchType.Lazy),当需要的时候才查询,不需要就不查询,但是感觉这种方式治标不治本,尤其是在那种报表统计查询的时候更为明显。

2.二级缓存,第一次查询之后存在内存中,后面的相同查询就快了。但是有2个缺点:a.二级缓存首先是有点浪费内存空间,如果多了的话浪费还比较严重,这是一个不好的方面,当然这不是主要的,主要的问题在于,二级缓存的特性决定的,那就是很少的增删改才做二级缓存,而对于普通的CRUD系统,其实不太适合。所以感觉也不是首选。

3.fetch="join",默认是fetch="select",这个其实说白了就是一个做外连接,允许外键为空的情况之下

在hibernate中成为迫切左外连接检索策略,其利用了SQL的外连接查询功能,能够减少select语句的数目。

使用HQL的LEFT OUTER JOIN.

List<Topic> topics = (List<Topic>)session.createQuery("from Topic t left join fetch t.category c").list();

或者在条件查询中使用setFetchMode(FetchMode.JOIN)

Customer ctm = (Customer)session.createCriteria(Customer.class)

                    .setFetchMode(“Order”.JOIN)

                    .add(Restrictions.idEq(customer_id));



原创粉丝点击