jvm调优与能 JVM性能调优

seosqwseo2个月前 (09-08)测评日记23

一、jvm的理解

我们在编写程序时,经常会遇到OOM(out of Memory)以及内存泄漏等问题。为了避免出现这些问题,我们首先必须对JVM的内存划分有个具体的认识。JVM将内存主要划分为:方法区、虚拟机栈、本地方法栈、堆、程序计数器。JVM运行时数据区如下:

程序计数器是线程私有的区域,很好理解嘛~,每个线程当然得有个计数器记录当前执行到那个指令。占用的内存空间小,可以把它看成是当前线程所执行的字节码的行号指示器。如果线程在执行Java方法,这个计数器记录的是正在执行的虚拟机字节码指令地址;如果执行的是Native方法,这个计数器的值为空(Undefined)。

此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。

与程序计数器一样,Java虚拟机栈也是线程私有的,其生命周期与线程相同。

本质上来讲,就是个栈。里面存放的元素叫栈帧,栈帧好像很复杂的样子,其实它很简单!它里面存放的是一个函数的上下文,具体存放的是执行的函数的一些数据。执行的函数需要的数据无非就是局部变量表(保存函数内部的变量)、*作数栈(执行引擎计算时需要),方法出口等等。

执行引擎每调用一个函数时,就为这个函数创建一个栈帧,并加入虚拟机栈。换个角度理解,每个函数从调用到执行结束,其实是对应一个栈帧的入栈和出栈。

注意这个区域可能出现的两种异常:

一种是StackOverflowError,当前线程请求的栈深度大于虚拟机所允许的深度时,会抛出这个异常。制造这种异常很简单:将一个函数反复递归自己,终会出现栈溢出错误(StackOverflowError)。

另一种异常是OutOfMemoryError异常,当虚拟机栈可以动态扩展时(当前大部分虚拟机都可以),如果无法申请足够多的内存就会抛出OutOfMemoryError,如何制作虚拟机栈OOM呢,参考一下代码:

这段代码有风险,可能会导致*作系统假死,请谨慎使用~~~

本地方法栈与虚拟机所发挥的作用很相似,他们的区别在于虚拟机栈为执行Java代码方法服务,而本地方法栈是为Native方法服务。与虚拟机栈一样,本地方法栈也会抛出StackOverflowError和OutOfMemoryError异常。

Java堆可以说是虚拟机中大一块内存了。它是所有线程所共享的内存区域,几乎所有的实例对象都是在这块区域中存放。当然,随着JIT编译器的发展,所有对象在堆上分配渐渐变得不那么“绝对”了。

Java堆是垃圾收集器管理的主要区域。由于现在的收集器基本上采用的都是分代收集算法,所有Java堆可以细分为:新生代和老年代。在细致分就是把新生代分为:Eden空间、From Survivor空间、To Survivor空间。当堆无法再扩展时,会抛出OutOfMemoryError异常。

方法区存放的是类信息、常量、静态变量等。方法区是各个线程共享区域,很容易理解,我们在写Java代码时,每个线程度可以访问同一个类的静态变量对象。由于使用反射机制的原因,虚拟机很难推测那个类信息不再使用,因此这块区域的回收很难。另外,对这块区域主要是针对常量池回收,值得注意的是JDK1.7已经把常量池转移到堆里面了。同样,当方法区无法满足内存分配需求时,会抛出OutOfMemoryError。

制造方法区内存溢出,注意,必须在JDK1.6及之前版本才会导致方法区溢出,原因后面解释,执行之前,可以把虚拟机的参数-XXpermSize和-XX:MaxPermSize限制方法区大小。

运行后会抛出java.lang.OutOfMemoryError:PermGen space异常。

解释一下,String的intern()函数作用是如果当前的字符串在常量池中不存在,则放入到常量池中。上面的代码不断将字符串添加到常量池,终肯定会导致内存不足,抛出方法区的OOM。

下面解释一下,为什么必须将上面的代码在JDK1.6之前运行。我们前面提到,JDK1.7后,把常量池放入到堆空间中,这导致intern()函数的功能不同,具体怎么个不同法,且看看下面代码:

这段代码在JDK1.6和JDK1.7运行的结果不同。

JDK1.6结果是:false,false,JDK1.7结果是true, false。

原因是:JDK1.6中,intern()方**吧首次遇到的字符串实例**到常量池中,返回的也是常量池中的字符串的引用,而StringBuilder创建的字符串实例是在堆上面,所以必然不是同一个引用,返回false。

在JDK1.7中,intern不再**实例,常量池中只保存首次出现的实例的引用,因此intern()返回的引用和由StringBuilder创建的字符串实例是同一个。为什么对str2比较返回的是false呢?这是因为,JVM中内部在加载类的时候,就已经有"java"这个字符串,不符合“首次出现”的原则,因此返回false。

二、jvm调优如何做

1、如果没有必要,请不要做调优。没有万能的调优,只有根据使用场景选择合适的手段,初始默认指定堆大小,元空间大小(jdk8)即可

2、确认性能问题由JVM再考虑调优,如fullGC频繁,GC时间较长,内存使用不正常,OOM等。开启JVM监控,记录GC日志,分析GC情况

3、JVM调优的目标是减少/避免老年代GC

4、对于追求响应时间的如web系统使用并发垃圾回收器(jdk8开启G1,低版本使用CMS)

5、根据JVM内存使用情况,可以考虑手动设置年轻代大小,survivor区大小,减少/避免垃圾进入老年代(注意jdk8默认开启自适应调节,需关闭)

6、影响GC时间的还有GC线程数等等,需要结合GC日志分析GC过程可能存在的问题

三、JVM性能调优***G1

1、本篇是对Java**G1收集器调优的精简版。针对G1垃圾的收集阶段可能出现的问题,非合理内存分配,大对象占用,Full GC等问题作出解决方式和*作参数。

2、 G1是一个吞吐量和时间延迟之间相互平衡的收集器。目标是高吞吐量下提供相对较小、统一的暂停。

3、所以如果是交互性强的应用程序,使用G1时需要基于时延优先进行考虑。

4、虚拟机从*作系统内存中分配或归还内存可能会导致不必要的延迟。通过使用选项-Xms和-Xmx将小和大堆大小设置为相同的值,并使用- XX:+AlwaysPreTouch预触摸所有内存,以将这项工作移到VM启动阶段,从而避免延迟。

5、并行处理 Reference对象,ParallelRefProcEnabled默认值false,若 GC log里出现 Reference处理时间较长的日志,可以开启此参数- XX:+ParalleRefProcEnabled。开启后会使用jvm可用的线程数进行处理,但**上提到的-XX:ReferencesPerThread参数在jdk17的版本中没有找到,猜测可能是jvm内部控制不再作可调试的参数。

6、年轻代收集所花费的时间大致与年轻代的大小成正比。**给出的两个参数- XX:G1NewSizePercent,-XX: G1MaxNewSizePercent在jdk17中没有找到,在没有固定年轻代大小时,G1会进行动态调整,所以这个调优的参考性不大,可以忽略。

7、 RS是一个抽象的数据结构,具体的实现由table card完成。一般会把记忆集和卡表放在一起讨论。简单来讲就是所有对象引用关系的一个**,GCRoot时扫描的不是去实际的内存区域,否则跨代引用时从新生代到老年代会是一个漫长的过程。RS很好的解决了跨代引用的问题。由于RS会动态更新,垃圾收集必须先等RS更新完毕后才去执行。所以RS更新如果耗时过长则会影响回收时间。

8、扫描RS时间也由G1为保持低存储容量而执行的压缩量决定。记忆的**存储在内存中越紧凑,在垃圾收集期间检索存储的值所花费的时间就越多。G1自动执行这种压缩,称为记忆集粗化,同时根据该区域记忆集的当前大小更新记忆集。特别是在高压缩级别时,检索实际数据可能非常慢。

9、使用选项- XX:G1SummarizeRSetStatsPeriod结合gc+remset=trace级别日志显示是否发生粗化。

相关文章

绿联USB/Type-C读卡器3.0高速好不好用

绿联USB/Type-C读卡器3.0高速好不好用

很多小伙伴在关注绿联USB/Type-C读卡器3.0高速怎么样?质量好不好?使用测评如何?本文综合已购用户的客观使用分享和相应的优惠信息,为大家推荐一款高性价比的产品,一起...

科大讯飞智能办公本Air7.8英寸电子书阅读器口碑好不好

科大讯飞智能办公本Air7.8英寸电子书阅读器口碑好不好

很多小伙伴在关注科大讯飞智能办公本Air7.8英寸电子书阅读器怎么样?质量好不好?使用测评如何?本文综合已购用户的客观使用分享和相应的优惠信息,为大家推荐一款高性价比的产品...

有道英语听力宝复读机学习机英语语文学习提升神器好不好

有道英语听力宝复读机学习机英语语文学习提升神器好不好

很多小伙伴在关注有道英语听力宝复读机学习机英语语文学习提升神器怎么样?质量好不好?使用测评如何?本文综合已购用户的客观使用分享和相应的优惠信息,为大家推荐一款高性价比的产品...

华为智选海雀智能家用摄像头3K图文测评

华为智选海雀智能家用摄像头3K图文测评

很多小伙伴在关注华为智选海雀智能家用摄像头3K怎么样?质量好不好?使用测评如何?本文综合已购用户的客观使用分享和相应的优惠信息,为大家推荐一款高性价比的产品,一起来看看吧。...

PICO4质量怎么样

PICO4质量怎么样

很多小伙伴在关注PICO4怎么样?质量好不好?使用测评如何?本文综合已购用户的客观使用分享和相应的优惠信息,为大家推荐一款高性价比的产品,一起来看看吧。...

小天才电话手表Q2A长续航儿童手表GPS定位智能手表价格是多少

小天才电话手表Q2A长续航儿童手表GPS定位智能手表价格是多少

很多小伙伴在关注小天才电话手表Q2A长续航儿童手表GPS定位智能手表怎么样?质量好不好?使用测评如何?本文综合已购用户的客观使用分享和相应的优惠信息,为大家推荐一款高性价比...