Jvm优化指南

简介: Jvm优化指南

Jvm优化指南

Jvm简介

JVMJava Virtual MachineJava虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。

引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。

Java Hotspot vm参数配置

-client -server -classpath / -cp

-verbose :class 输出jvm载入类的相关信息,当jvm报告说找不到类或者类冲突时可此进行诊断。

-verbose:gc 输出每次GC的相关情况

-verbose:jni 输出native方法调用的相关情况,一般用于诊断jni调用错误信息。

jvm参数

Heapsize 堆栈大小

-Xms 定义最小值 -Xmx 定义最大值  建议设置相同,防止垃圾收集器在最小、最大之间收缩堆而产生额外开销。

GC垃圾回收--新生代New配置

-XX:newSize

-XX:MaxNewSize

建议设置相同,防止年轻代的堆收缩。

GC垃圾回收旧生代Old配置 -XX:NewRadio=2表示新生代:老年代 = 1:2

Jit编译器:c1/c2

HotSpot VM中内嵌有两个JIT编译器,分别为Client CompilerServer Compiler,但大多数情况下我们简称为C1编译器和C2编译器。开发人员可以通过如下命令显式指定Java虚拟机在运行时到底使用哪一种即时编译器,如下所示:

C1编译器会对字节码进行简单和可靠的优化,以达到更快的编译速度;而C2编译器会启动一些编译耗时更长的优化,以获取更好的编译质量。

垃圾回收

Java的堆内存模型

 

新生代(Young generation)

绝大多数被新建的对象会分配到这里,由于大部分对象在创建后会很快变得不可达,所以很多对象被创建在新生代,然后消失,对象消失的过程称为”minor GC”

新生代存在1eden区和2survivor,新对象会首先分配到eden,当然如果对象过大会直接分配到老年代,gc,eden中的对象会被移动到survivor,直到对象满足一定年纪(熬过gc的次数),会被移动到老年代

可以设置新生代和老年代的相对大小,这种方式的优点是新生代的大小随着堆内存的动态扩展,设置方式为-XX:NewRatio,例如-XX:NewRatio=8代表老年代/新生代为8/1,老年代占堆内存的7/8,新生代占1/8

老年代(Old generation)

对象没有变的不可达,在新生代中存活下来的对象会被拷贝到这里,其占用的空间比新生代多,因为其占用空间大,所以发生在老年代上的gc比新生代少,对象从老年代消失的过程称之为”major GC”或者”full GC”

永久代(permanent generation)

像一些类级的层次信息,方法数据和方法信息,运行时常量(jdk1.7之后移除永久代),已确定的符号引用和虚方法表等等,它几乎是静态的很少被回收,jdk8之前的hotspot虚拟机中,类的这些永久的数据存放在一个叫做永久代的区域,jvm启动时可以设置-XX:MaxPermsize的值来控制永久代的大小,但是jdk1.8之后取消了永久代,这些元素被移到了与堆不相连的本地内存区域

Gc参数

hotspot实现垃圾回收细节

一致性

一致性要求gc进行时必须停顿所有java执行线程

安全点

程序只有达到安全点才能暂停,安全点的标准就是是否让程序长时间执行的特征,比如方法调用和循环跳转这种,具有这些才会产生安全点

程序暂停的2种方式

抢先式中断:gc发生时,主动中断所有线程

主动式中断:设一个标志,各线程去轮询这个标志,遇到中断则暂停,轮询地方与安全点重合

垃圾收集器

Serial收集器

Serial收集器是最基本,发展历史最悠久的收集器,曾经(jdk1.3.1之前)是虚拟机新生代收集的唯一选择

这是一个单线程收集器。意味着它只会使用一个 CPU 或一条收集线程去完成收集工作,并且在进行垃圾回收时必须暂停其它所有的工作线程直到收集结束。

它的优势在于简单而高效,对于限定单个CPU来说,由于serial收集器没有线程交互的开销,专心做垃圾收集自然能获得最高的单线程收集效率

ParNew 收集器

ParNew收集器其实就是serial收集器的多线程版本,除了使用多线程执行垃圾回收外,其余行为跟serial收集器一模一样,例如在回收算法和回收策略,分配规则都是一样的,在实现上这2种收集器共用了很多代码

Parnew的应用场景:是运行在server模式下的虚拟机的首选新生代垃圾回收器,因为它是除serial收集器外唯一能与cms收集器配合工作

Serial收集器与parnew收集器比较

Parnew收集器在单cpu环境下绝对不会比serial收集器有更好的效果,因为它存在线程的交互开销,但是随着可以使用的CPU数量增加,它对于gc时系统资源的有效利用还是很好的

Parallel Scavenge 收集器

是一个新生代收集器,也是使用复制算法实现,同时也是并行的多线程收集器。应用场景主要是针对那些需要频繁与用户交互的程序,良好的响应速度能提升用户体验

Serial Old 收集器

Serial收集器的老年代版本,单线程,使用标记整理算法。

应用场景:

Client模式:serial old收集器主要意义在于给client模式下的虚拟机使用

Server模式:server模式下有2大用途:一种用途是在jdk1.5之前与Parallel Scavenge 收集器配合使用,另一种用途是作为cms收集器的备用预案,在并发收集失败时使用

Parallel Old 收集器

Parallel Old Parallel Scavenge 收集器的老年代版本。多线程,使用标记整理算法

应用场景:在注重吞吐量以及CPU资源敏感的场合,可以优先考虑Parallel Old Parallel Scavenge 收集器

这个收集器是在jdk1.6中才提供的

CMS 收集器

CMS (Concurrent Mark Sweep) 收集器是一种以获取最短回收停顿时间为目标的收集器。基于标记清除算法实现。

运作步骤:

初始标记(CMS initial mark):标记 GC Roots 能直接关联到的对象,需要”stop the world”

并发标记(CMS concurrent mark):进行 GC Roots Tracing

重新标记(CMS remark):修正并发标记期间的变动部分,仍然需要”stop the world”

并发清除(CMS concurrent sweep):会清除对象

缺点:

1,cms收集器对CPU资源比较敏感,cms默认启动的回收线程数是(CPU数量+3)/4,也就是CPU4个以上时,并发回收时垃圾收集线程不少于25%CPU资源,并随着CPU数量的增加而下降,但是,如果CPU不足4个时,cms对用户程序的影响变得很大

2,cms收集器无法处理浮动垃圾,可能出现”concurrent mode failure”失败而导致另一次full gc产生

3,cms收集器会产生大量空间碎片,因为它是基于标记-清除算法的收集器,故在收集结束时会产生大量空间碎片,空间碎片过多会给大对象分配带来很大麻烦,比如老年代还有很大空间剩余,但是无法找到更大的连续空间来分配对象从而不得不提前触发一次full gc

G1 收集器

G1(garbage first)是一款面向服务端应用的垃圾收集器,Hotspot开发团队是希望用它替换掉jdk1.5中发布的cms收集器

G1的优点:并行与并发、分代收集、空间整合、可预测停顿。

运作步骤:

 

初始标记(Initial Marking)

并发标记(Concurrent Marking)

最终标记(Final Marking)

筛选回收(Live Data Counting and Evacuation)

实例分析

实例1

java.lang.OutOfMemoryError: GC overhead limit exceeded

通过Linux查看进程的命令ps -ef|grep java发现

-xms768m -xmx768m -xx:NewSize=320m, -xx:MaxNewSize=320m

通过分析应用堆区内存设置只有768m,机器内存有2g,机器上只跑了一个java应用,没有其他需要占内存的地方,另外,这个应用比较大,需要占得内存比较比较多所以修改配置如下

-xms1280m -xmx1280m -xx:NewSize=500m, -xx:MaxNewSize=500m

跟踪运行情况发现,异常没有再出现,问题解决

实例2

一个服务系统,经常出现卡顿,分析原因,发现full gc时间太长

Jstat -gcutil:

S0     S1    E     O     P       YGC     YGCT   FGC   FGCT     GCT

12.16  0.00  5.18   63.78  20.32    54    2.047    5     6.946    8.993

分析上面的数据,发现YGC执行54,耗时2.047,每次YGC耗时37ms,在正常范围,FGC执行了5,耗时6.946,每次耗时1.389秒数据显示问题

Full gc耗时较长,分析该系统发现-XX:NewRadio=9,也就是新生代和老年代的比例是1:9

这会造成:

1,新生代内存太小,导致对象提前进入老年代,从而触发full gc

2,老年代较大,进行full gc耗时较长

解决方法是将-XX:NewRadio=4,意思是将对象控制在新生代就清理掉,没有进入老年代(这种做法针对一些应用有效,并不是所有应用都有效)

总结

1,多数的Java应用不需要在服务器上进行GC优化;

2,多数导致GC问题的Java应用,都不是因为我们参数设置错误,而是代码问题;

3,在应用上线之前,先考虑将机器的JVM参数设置到最优(最适合)

4,减少创建对象的数量

5,减少使用全局变量和大对象;

6,GC优化是到最后不得已才采用的手段

7,在实际使用中,分析GC情况优化代码比优化GC参数要多得多

GC优化的目的有2

1,将转移到老年代的对象数量降低到最少

2,减少full gc的执行时间

为达目的可以这样做:

1,减少使用全局变量和大对象

2,调整新生代的大小到最合适

3,设置老年代的大小为最合适

4,选择合适的GC收集器

 

 

 

 

 

 

 

相关文章
|
7月前
|
前端开发 Java 编译器
深入理解jvm - 编译优化(上)
深入理解jvm - 编译优化(上)
128 0
|
25天前
|
监控 算法 Java
Java虚拟机(JVM)垃圾回收机制深度剖析与优化策略####
本文作为一篇技术性文章,深入探讨了Java虚拟机(JVM)中垃圾回收的工作原理,详细分析了标记-清除、复制算法、标记-压缩及分代收集等主流垃圾回收算法的特点和适用场景。通过实际案例,展示了不同GC(Garbage Collector)算法在应用中的表现差异,并针对大型应用提出了一系列优化策略,包括选择合适的GC算法、调整堆内存大小、并行与并发GC调优等,旨在帮助开发者更好地理解和优化Java应用的性能。 ####
32 0
|
24天前
|
存储 监控 算法
Java虚拟机(JVM)垃圾回收机制深度解析与优化策略####
本文旨在深入探讨Java虚拟机(JVM)的垃圾回收机制,揭示其工作原理、常见算法及参数调优方法。通过剖析垃圾回收的生命周期、内存区域划分以及GC日志分析,为开发者提供一套实用的JVM垃圾回收优化指南,助力提升Java应用的性能与稳定性。 ####
|
1月前
|
监控 算法 Java
Java虚拟机垃圾回收机制深度剖析与优化策略####
【10月更文挑战第21天】 本文旨在深入探讨Java虚拟机(JVM)中的垃圾回收机制,揭示其工作原理、常见算法及参数调优技巧。通过案例分析,展示如何根据应用特性调整GC策略,以提升Java应用的性能和稳定性,为开发者提供实战中的优化指南。 ####
42 5
|
1月前
|
监控 Java 开发者
Java虚拟机(JVM)深度优化指南####
本文深入探讨了Java虚拟机(JVM)的工作原理及其性能优化策略,旨在帮助开发者通过理解JVM的内部机制来提升Java应用的运行效率。不同于传统的技术教程,本文采用案例分析与实战技巧相结合的方式,为读者揭示JVM调优的艺术。 ####
58 8
|
29天前
|
存储 IDE Java
实战优化公司线上系统JVM:从基础到高级
【11月更文挑战第28天】Java虚拟机(JVM)是Java语言的核心组件,它使得Java程序能够实现“一次编写,到处运行”的跨平台特性。在现代应用程序中,JVM的性能和稳定性直接影响到系统的整体表现。本文将深入探讨JVM的基础知识、基本特点、定义、发展历史、主要概念、调试工具、内存管理、垃圾回收、性能调优等方面,并提供一个实际的问题demo,使用IntelliJ IDEA工具进行调试演示。
34 0
|
5月前
|
缓存 安全 算法
Java面试题:如何通过JVM参数调整GC行为以优化应用性能?如何使用synchronized和volatile关键字解决并发问题?如何使用ConcurrentHashMap实现线程安全的缓存?
Java面试题:如何通过JVM参数调整GC行为以优化应用性能?如何使用synchronized和volatile关键字解决并发问题?如何使用ConcurrentHashMap实现线程安全的缓存?
62 0
|
2月前
|
Arthas 监控 Java
JVM知识体系学习七:了解JVM常用命令行参数、GC日志详解、调优三大方面(JVM规划和预调优、优化JVM环境、JVM运行出现的各种问题)、Arthas
这篇文章全面介绍了JVM的命令行参数、GC日志分析以及性能调优的各个方面,包括监控工具使用和实际案例分析。
75 3
|
2月前
|
存储 算法 Java
深入理解Java虚拟机(JVM)及其优化策略
【10月更文挑战第10天】深入理解Java虚拟机(JVM)及其优化策略
56 1
|
2月前
|
监控 Java
Java的JVM如何优化?
Java的JVM如何优化?
67 3