Web项目出现周期性卡顿的原因分析

近段时间接触的一个项目,在实际使用以及测试的时候回经常出现卡顿的现象,一开始以为这种情况不常见,但是后来发现这种卡顿会周期性的出现,所以想找找原因:

1,JVM虚拟机垃圾回收

jvm虚拟机将堆分为新生代老年代,而当我们去new一个对象的时候,这个对象就会进入到新生代区里面,新生代用于存放刚创建的对象以及年轻的对象,如果对象一直没有被回收,生存得足够长,对象就会被移入老年代,那么一直进行以上过程,那么老年代中的活着的对象就会越来越多,最后老年代满了以后就会触发Full GC操作,即垃圾回收

那么当jvm虚拟机进行垃圾回收(GC,Garbage Collection)时候出现的STW(Stop-The-World)动作会使正在工作的线程停止工作,待回收完毕时候线程才会重新工作,即当Stop-the-world发生时,除了GC所需的线程以外,所有线程都处于等待状态直到GC任务完成,所以这个工作在时间上会有消耗,导致系统的性能会有所下降,最后可能周期性卡顿的原因就是JVM在进行垃圾回收操作。

这时候jstat命令就可以帮我们更好地判断JVM垃圾回收是否正常,如下图就记录了一次周期性卡顿出现时,JVM垃圾回收的情况:(在JDK的bin目录下进行cmd即可运行jstat命令)

由上图可见Full GC(FGC)参数值很大,说明垃圾回收进行得很频繁,Full GC总耗时(FGCT)为16.743秒,导致系统卡顿的现象出现。

那么如何解决呢?可以通过调整新生代与老年代的比例,调低老年代占的内存大小,这样老年代很快就被写满了,就会提前进行垃圾回收,回收完毕线程重新工作,这个过程可能用户察觉不出来,因为老年代分配到的内存不多,所以耗时会较少,当然比例的调整也要根据每个系统的情况来定。

2,代码性能

当然啦,我们自己本身写的代码也是影响性能的一个因素,总结出本人平时一些优化Java代码性能的方式(或者说是一些编程习惯吧):

1.若需频繁对字符拼接修改的时候少用String,可以用StringBuilder或者StringBuffer

引用网上的一段话:

“简要的说, String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象, 因此在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,那速度是一定会相当慢的。”

2.list的选择(对于ArrayList与LinkedList)

对于长度规定的用数组。
对于随机访问get操作,ArrayList优于LinkedList,因为LinkedList要移动指针
对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据

当然啦,除了以上两点外,服务器的配置也是影响系统性能的一个因素,如果代码已经足够优化了,但是服务器配置跟不上,卡顿的现象也还是会出现的~

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值