java培训:JVM性能调优理论基础知识分享

JVM是Java虚拟机,它是一个虚构出来的计算机,可在实际的计算机上模拟各种计算机的功能。JVM有自己完善的硬件结构,例如处理器、堆栈和寄存器等,还具有相应的指令系统。JVM在整个JDK中处于最底层,负责与操作系统的交互。因此掌握JVM调优便显得尤为重要。在进行JVM调优介绍之前,让我们来简单介绍一下基础知识吧!

1. 什么是垃圾?

在C语言中,我们通过malloc和free来申请和释放内存;在C++语言中我们通过new和delete来申请和释放内存。那么Java语言当我们new了一个对象之后,发生了什么?怎样进行内存的申请和释放的呢?事实上, Java语言是通过GC自动进行内存回收的,java培训从而简化编程,使系统不太容易出错,因为手动释放内存容易造成遗漏回收和重复回收的问题。如果程序中出现了没有任何引用指向的对象,我们将这样的对象称为垃圾。

2. 如何定位垃圾?

定位垃圾一般有2种算法,引用计数法和根可达算法。

①引用计数(Reference Count)

引用计数是计算机编程语言中的一种内存管理技术,是指将对象的被引用次数保存起来,当被引用次数变为零时就将其释放的过程。使用引用计数技术可以实现自动资源管理的目的。同时引用计数还可以指使用引用计数技术回收未使用资源的垃圾回收算法。

 

但是引用技术法无法解决循环引用的问题,如下图:

 

②根可达算法(RootSearching)

根可达算法的基本思路就是通过一系列名为”GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。GC Roots包含的元素主要包括:虚拟机栈中引用的对象,本地方法栈JNI引用的对象,方法区中类静态属性引用的对象,方法区中常量引用的对象,所有被同步锁synchronized持有的对象等。

 

从上图可以看出有2个对象都是GC Roots,已经用黑色方框圈出,可以看出对象1,2,3,4,5,6,7都具有GC Roots可达性,也就是存活对象,不能被GC回收的对象。而对于对象实例Garbage并没有任何一个GC Roots与之相连,这便是GC Roots不可达的对象,这就是GC需要回收的垃圾对象。

3. 常见的垃圾回收算法

①标记清除

标记-清除是一种非常基础和常见的垃圾回收算法。算法分为两个阶段,标记阶段和清除阶段。他们找出所有不可达的对象。并将他们放入空闲列表,这个空闲列表就是垃圾回收的列表,标记阶段标记出所有需要回收的对象,清除阶段回收所有被标记对象所占用的空间。

 

缺点是:容易产生内存碎片。

②拷贝算法

拷贝算法的出现是为了解决标记-清除算法产生的内存碎片。拷贝算法的思路是:首先将内存分为大小相等的两部分(A,B两部分),每次只使用其中的一部分(这里假设为A区),等A区部分用完了,这时候就将这里面还能活下来的对象复制到另一部分内存(这里设为B区)中,然后把A区中的剩下部分全部清理掉。这样一来每次清理都要对一半的内存进行回收操作,这样内存碎片的问题就解决了,可以说简单,高效。

 

③标记压缩

既然叫标记-压缩算法,那么它也分为两个阶段,一个是标记(mark),一个是压缩(compact). 其中标记阶段跟标记-清除算法中的标记阶段是一样的。

 

而对于压缩阶段,它的工作就是移动所有的可达对象到堆内存的同一个区域中,使他们紧凑的排列在一起,从而将所有非可达对象释放出来的空闲内存都集中在一起,通过这样的方式来达到减少内存碎片的目的。

4.JVM内存分代模型

JVM不同的垃圾回收器所具有的分代模型有所区别,总体的可以分为逻辑分代和物理分代。除Epsilon、ZGC、Shenandoah之外的GC均采用逻辑分代模型,包含Serial、Serial Old、Parallel Scavenge、Parallel Old、ParNew 、CMS、G1等垃圾回收器,其中,G1只是逻辑分代但是物理不分代,其他的垃圾回收器既是逻辑分代也是物理分代。

逻辑分代模型如下图所示,其中可分为两代young新生代和old老年代,java培训机构除了G1和Shenandoah等垃圾回收期外的其他垃圾回收期中,这两部分内存所占的比例大致为1:3的关系,不过这个关系是可改的。新生代主要存放的对象是刚刚new出来的对象,老年代存放的对象是垃圾回收已经回收好多次了,但是仍然没有将其回收掉。

新生代中又可分为eden伊甸区和两个survivor区,内存分配的比例大致是8:1:1,在垃圾回收期间,将Eden区和survivor1区/survivor2区的存活对象一次性复制到survivor2区/survivor1区空间,所以只有10%的新生代空间是被浪费的,但还有个问题,如果转移复制的时候存活对象超过了10%,那么将通过分配担保直接将这些对象放入老年代。

 

对象new出来之后,首先进行栈上分配,如果分配不下则进入Eden区,在Eden区经过一次垃圾回收到servivor1区,再经过垃圾回收到servivor2区,然后经过不断的垃圾回收一直在servivor1区和servivor区徘徊,最后年龄到了之后,到达Old老年代。因为新生代中只有少量对象存活下来,大部分对象都被清理掉了,所以适合采用拷贝算法。因为老年代中大量的对象都存活着,只有少量对象被清理掉,所以适合采用标记清除算法或标记压缩算法。其中在新生代的垃圾回收我们称之为YGC,其中老年代如果内存满了老年代进行的垃圾回收我们称之为FGC(Full GC)。

常见的垃圾回收器

自从JDK诞生以来,诞生了许多垃圾回收器,诸如Serial、ParNew、Parallel Scavenge、Serial Old、Parallel Old、CMS、G1,ZGC,Shenandoah,Eplison等。

 

其中Epsilon是一款仅用于调试的垃圾回收器,这里不做过多的讨论。

新生代垃圾回收器主要包括:Serial、ParNew、ParallelScavenge;

老年代垃圾回收器主要包括: SerialOld、CMS、Parallel Old。

G1只在逻辑上分代,ZGC和Shenandoah不分代。

①Serial & Serial Old:

分别是新生代和老年代的垃圾回收器,串行回收,现在一般不用了。当垃圾回收线程工作的时候,会停止一切工作线程,只进行垃圾回收。这种场景称之为STW(Stop-The-World)阶段。由于Serial收集器进行垃圾回收时的等待时间,即STW时间较长,所以只适合在内存空间较小的情况下使用。Serial Old是老年代的垃圾回收器,采用标记清除或标记压缩算法。

②Parallel Scavenge和Parallel Old

因为单线程的效率低,内存空间日益变多,现在常用的是这两种回收器的组合,称为为PS+PO,这两种在①的基础上增加了多线程。在一定程度上提高了垃圾回收的效率。PO使用标记压缩算法。这两个组合也是JDK1.8的默认垃圾回收器。

③ParNew&CMS

由于PS+PO组合还是存在很长时间的STW,有的甚至长达几个小时或几天,那有没有一种可以与工作线程并发执行的垃圾回收器呢?CMS便出现了。ParNew是年轻代的垃圾回收器配合CMS进行并行回收,是Parallel Scavenge的升级。CMS的英文全程是ConcurrentMarkSweep,是在老年代并发的,垃圾回收和应用程序同时运行,以降低STW的时间,但是CMS同样也存在很多问题,所以现在没有一个版本默认是CMS,只能手动指定。CMS既然是MarkSweep就会产生很多碎片化问题,碎片产生到一定程度,对象分配不下的时候,就使用SerialOld进行老年代回收。

④ G1

G1是一款面向服务端应用的垃圾回收器。G1 垃圾回收器的大致可划分为以下几个步骤:

初始标记(Initial Marking)--标记一下GC Roots能直接关联到的对象。

并发标记(ConcurrentMarking)—从GC Root开始对堆中对象进行可达性分析,找出存活的对象,这阶段耗时较长,但可与用户程序并发执行。

最终标记(FinalMarking)—为了修正在并发标记期间因用户程序继续运作而导致标记产生变动的那一部分标记记录。虚拟机将这段时间对象变化记录在线程Remembered Set Logs里面,最终标记阶段需要把Remembered Set Logs的数据合并到Remembered Set中筛选回收(Live Data Counting and Evacuation)。

G1相对于CMS的优势在于:降低停顿时间是 G1 和 CMS 共同的关注点,但 G1 除了追求低停顿外,还能建立可预测的停顿时间模型。

⑤ ZGC & Shenandoah

Shenandoah GC 与 ZGC 同为新一代的低延迟收集器, 使用颜色指针算法,分别由RedHat和Oracle开发, 目前还在实验阶段, 尚未使用于生产环境。

目前主流GC是G1, 而此两者的延时比G1低很多。

6.垃圾回收器和内存大小的关系

Serial适合于内存较小的机器,一般适合于几十M,PS适合于内存上百M到几个G之间的内存,CMS适合于20G左右的内存,G1适合于上百G左右的内存,ZGC和Shenandoah适合于4T---16T的超大内存。

文章来源于沃享荟

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值