JVM(九)有关JVM的调优的见解

背景:

         这篇文章并不是仔细来详解有关JVM调优的方式,作为一个初学JVM的新手要做到如何如何精通各种调优规则对于我来说确实是太勉强了。那我为什么要写下这篇博客呢?对于个人而来主要是为了把知识体系先系统化,以后进行细枝末节的补充。而这篇文章记录的只是在视频学习中的一些理论上的调优规则,毕竟本人并没有任何实际实战经验。在日后发展学习中,会慢慢对内容进行补充和完善。

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

JVM调优:

   预备知识:

  1. 掌握GC相关的VM参数,会基本的空间调整
  2. 掌握相关的工具
  3. 明白一点,调优规则并不是固定,要根据具体情形进行分析

1.有关GC的VM参数就是一些堆内存大小分配,栈内存大小分配,新生代内存分配等等。具体的操作可以参考如下这篇整理的文章

https://blog.csdn.net/wang379275614/article/details/78471604

2.掌握相关工具则是一些有关内存的监视工具,常用的有jconsole工具,jmap命令,jvisual工具等等。

 

   调优方向:

  1. 内存
  2. 锁竞争
  3. CPU占用
  4. Io
  5. GC垃圾回收

我们要注意有关调优并不仅仅是GC垃圾回收的调优,调优的方向有很多很多。GC调优只是一个立竿见影,可以很容易的看见成效的调优,因为它影响着延迟时长,用户很容易的进行感知。

 

   调优第一步:(调优首先从代码进行调优)

 

   调优第二步:(从新生代开始调优)

(1)新生代是不是越大越好?

新生代较小的话会造成Minor-GC频发,出现STW时间增加。

新生代较大的话会造成老年代的内存就会变小,易发生垃圾回收(Full-GC),导致垃圾回收时间增加。

Oracle建议的新生代内存大小为:占用堆内存的25%-50% 

为什么会导致上图现象发生呢?

        新生代的复制算法分为标记和复制两个阶段,复制要花费的时间更多。而新生代的对象只有少量的对象能够存活,因此,复制的时间较少,即使新生代有较大的内存,回收的效率依旧不会太高

 

(2)幸存区的设置

幸存区要能够保留:当前活跃对象和需要晋升的对象

幸存区的晋升阈值设置要合理,阈值太大的话,幸存区的幸存对象会被多次复制,阈值过小的话,晋升后的对象进入老年带后就只有Full-GC的时候才会被清理。

 

   调优第三步:(从老年代开始调优)

以CMS为例:

  1. CMS的老年代内存越大越好:因为垃圾处理线程和用户的线程是并发的,当垃圾处理的时候,用户的线程还会产生垃圾(浮动垃圾),如果再次导致内存不足,就会导致并发失败。退化为Serial-old,串行的垃圾回收器,响应时间较长。
  2. 先尝试不去调优,因为如果未发生Full-GC,则证明老年代的内存正常,可以尝试调优新生代。
  3. 如果老年代发生了Full-GC,就去观察发生Full-GC的时候老年代的内存占用,将老年代的内存预设调大1/4-1/3。

 

JVM调优看法:

来源:https://www.zhihu.com/question/362201242

问题:

一般的Java项目需要JVM调优吗?平常做的Java项目,SpringBoot直接打成jar包,然后部署,也没有设置什么 调优的参数,感觉这样做技术提升不了,大神能不能提点意见。

 

回答:

一般项目肯定是不需要的,即便是我参与的一些高并发服务的开发, 即便是每秒几万甚至上百万的请求数,对JVM的调优也不是那么重要的。因为JVM本身就是为这种低延时高并发大吞吐的服务设计和优化的,我们很少需要去改变什么。所以,我们往往更偏重于应用服务本身的调优。就算我把一些项目的JVM调优删掉部分或全部,它们多数还是可以跑的很好,当然,面对一些极端情况或许会有问题。

但如果你的服务有一定特殊性,JVM调优就会显出一定的必要性。比如说我最近在搞的presto,这种大数据计算引擎其实是一种非常极端的JVM应用,一般使用极大的heap,100到200个g也吃的掉,对延时的要求并不高,但对吞吐量要求很高,会有大量的短命对象,同时也有大量的对象生存时间非常久,我们就需要有特定的一些参数,比如说让gc中各个generation的分布更合理等等。虽然是个开源项目,但是每个公司都有自己的特殊性,参数也会不同,所以你真的要懂JVM调优,而不是去照抄别人的参数,而且你还要根据实际情况不断调整。但同样的,我们也还是以presto应用本身的调优为主,JVM调优只起到一个配合作用。

我是觉得现在不少公司面试Java程序员就盯着jvm问,是种舍本逐末。而我最不能忍的就是好多程序员解决问题喜欢一杆子捅到底层,遇到问题竟然会先想是不是JVM的bug,遇到延时高就会断定是gc算法有问题,竟然会先去考虑替换gc算法,这种自信我也是挺醉的。

其实我在实际开发中,反而没少遇到错误调节JVM参数导致的问题,比如说评论区中说的大量对象都直接去了老年区,导致频繁full GC。这种很多都是因为有人担心大对象在新生代频繁移动,就把eden设置的过小,导致很多对象不放eden只好去了老年代。但默认的设置怎么会经常出现这种情况?除非你应用程序就是有特殊的需要,但这种情况是少之又少。而且现在默认gc是G1,有humongous区,大对象不去eden触发full gc就更加不存在了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值