记一次难忘的调优

一、问题描述:

我们在平常开发中可能不会在意代码的质量导致后期的一系列问题,比如说我们在开发某公司的应用程序中遇到hibernate内存泄露的问题,重复创建的对象没有被垃圾回收器及时回收,导致weblogic堆溢出。

二、调优步骤:

2.1、发现问题:

在监控后台的时候发现,由于数据量太大(数据量千万级别),产生的对象太多,导致创建的对象一直堆积在堆内存中,程序运行3个小时后发生堆溢出的现象。

2.2、查找问题:

我们对代码进行了定位,发现在数据量很大的时候,会创建大量的对象要插入到数据库中,可是用hibernate的saveall方法进行分批插入的时候,实际数据并没有真正的插入到数据库中,而是先缓存到session中后,等到事务结束后才能真正插入到数据库中,所以导致堆内存不堪重负溢出。如果数据量够大的情况下,除非你的堆内存足够大才能不发生堆溢出,但是增加堆内存受到硬件的限制,所以这并不是解决问题的最佳方法。

有几款调优的软件挺好用,JDK自带的jvisualVM,在bin文件夹下。还有一个更加直观的软件,MAT(memory analyse tool),这个软件可以通过界面饼状图查看堆中对象的占用情况,也可以查看详细的对象,以方便找到调用它的地方找到内存泄露的原因。

2.3、解决问题:

优化第一步:增加weblogic的最大堆内存,修改设置环境的bat批处理文件的内容,修改Xmx(最大堆内存),建议越大越好,但是堆内存的最大最好不要超过机器内存的free值,否则的话就会发生启动服务器闪退问题。

优化第二步:修改hibernate调用处的逻辑,增加clear方法,这个方法用来清除hibernate的缓存。但是我发现一个问题,如果你单加clear就会把每次数据清除,没有写入数据库,所以在clear方法前你需要增加一个flush方法,先把缓存中的数据刷新写入数据库中,然后再清除缓存中的数据。

优化第三步:如果数据量很大的情况下,可以对数据库进行表分区,分散I/O。具体方法大家可以自己研究,我只提供一个idea。

优化第四步:优化sql语句和代码,sql中尽量不要使用in,可以用exists代替,尽量不要使用or字段,会全部扫描。代码方面的话,尽量在循环中不要进行其他计算操作,比如for循环最好写成for(int i=0,len=list.size();i<len;i++)这种形式,否则for每次都会计算,增加不必要的消耗。

优化第五步:给经常使用的字段建索引,如果普通表建议建联合索引,但是索引不要建太多,索引如果太大会占用大量的内存,导致适得其反。如果是分区表建议建本地索引,提高每个分区中查询的效率,不建议跨分区查询,效率也会很低。

三:总结:

总之,我们在平常编写程序的时候,需要注意代码的规范和性能,不要只追求完成功能。我们在开发过程中需要多注意细节,才能把程序完成的足够好!希望大家能从我的这篇文章中get到一些点,能够帮助到大家的学习和开发。




  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值