JVM(二)垃圾回收GC以及Tomcat性能测试

垃圾回收概念和算法及对象的分代转换

垃圾回收概念及其算法

谈到垃圾回收( Garbage Collection,简称GC),需要先澄清什么是垃圾,类比日常生活中的垃圾,我们会把他们丢入垃圾桶,然后倒掉。GC中的垃圾,特指存于内存中、不会再被使用的对象,而回收就是相当于把垃圾“倒掉”。

垃圾回收有很多种算法:如引用计数法、标记压缩法、复制算法、分代、分区的思想。

垃圾收集算法

引用计数法:这是个比较古老而经典的垃圾收集算法,其核心就是在对象被其他所引用时计数器加1,而当引用失效时则减1,但是这种方式有非常严重的问题:无法处理循环引用的情况、还有就是每次进行加减操作比较浪费系统性能。

 

标记清除法:就是分为标记和清除俩个阶段进行处理内存中的对象,当然这种方式也有非常大的弊端,就是空间碎片问题,垃圾回收后的空间不是连续的,不连续的内存空间的工作效率要低于连续的内存空间。

 

复制算法:其核心思想就是将内存空间分为两块,每次只使用其中一块,在垃级回收时,将正在使用的内存中的存留对象复制到未被使用的内存块中去,之后去清除之前正在使用的内存块中所有的对象,反复去交换俩个内存的角色,完成垃圾收集。(Java中新生代的from和to空间就是使用这个算法)

 

标记压缩法:标记压缩法在标记清除法基础之上做了优化,把存活的对象压缩到内存端,而后进行垃圾清理。(Java中老年代使用的就是标记压缩法)

 

分代算法:就是根据对象的特点把内存分成N块,而后根据每个内存的特点使用不同的算法。

对于新生代和老年代来说,新生代回收频率很高,但是每次回收耗时都很短,而老年代回收频率较低,但是耗时会相对较长,所以应该尽量减少老年代的GC。

 

分区算法:其主要就是将整个内存分为N多个小的独立空间,每个小空间都可以独立使用,这样细粒度的控制一次回收都少个小空间和那些个小空间,而不是对整个空间进行GC,从而提升性能,并减少GC的停顿时间

 

垃圾回收时的停顿现象

垃圾回收器的任务是识别和回收垃圾对象进行内存清理,为了让垃圾回收器可以高效的执行,大部分情况下,会要求系统进入一个停顿的状态。停顿的目的是终止所有应用线程,只有这样系统才不会有新的垃圾产生,同时停领保证了系统状态在某一个瞬间的一致性,也有益于更好低标记垃圾对象。因此在垃圾回收时,都会产生应用程序的停顿。

 

对象如何进入老年代

一般而言对象首次创建会被放置在新生代的eden区,如果没有GC介入, 则对象不会离开eden区,那么eden区的对象如何进入老年代呢?一般来讲,只要对象的年龄达到一定的大小,就会自动离开年轻代进入老年代,对象年龄是由对象经历数次GC决定的,在新生代每次大GC之后如果对象没有被回收则年龄加1。虚拟机提供了一个参数来控制新生代对象的最大年龄,当超过这个年龄范围就会晋升老年代。-XX: MaxTenuringThreshold,默认情况下为15

 

根据设置 MaxTenuringThreshold参数,可以指定新生代对象经过多少次回收后进入老年代

另外,大对象(新生代eden区无法装入时,也会直接进入老年代),JVM里有个参数可以设置对象的大小超过在指定的大小之后,直接晋升老年代.

-XX: PretenureSizeThreshold

 

使用 PretenureSizeThreshold可以进行指定进入老年代的对象大小,但是要注意TLAB区域优先分配空间。

 

TLAB

TLAB全称是ThreadLocalAllocationBuffer即线程本地分配缓存,从名字上看是一个线程专用的内存分配区域,是为了加速对象分配而生的。每一个些线程都会产生一个TLAB,该线程独享的工作区域,Java虚拟机使用这种TLAB区来避免多线程冲突问题,提高了对象分配的效率。TLAB空间一般不回会太大,当大对象无法在TLAB分配时,则会直接分配到堆上。

-XX:+ USETLAB使用TLAB

-XX:+ TLABSIZE设置TLAB大小

-XX: TLABRefillWasteFraction设置维护进入TLAB空间的单个对象大小,他是一个比例值,默认为64,即如果对象大于整个空间的1/64,则在堆创建对象。

-XX:+ PrintTLAB查看TLAB信息

-XX. ResizeTLAB自调整 TLABRefillWasteFraction阀值。

 

对象创建流程图

一个对象创建在什么位置,我们的JVM会有一个比较细节的流程,根据数据的大小,参数的设置,决定如何创建分配,以及其位置。

 

垃圾收集器

在cathalina.sh中配java_OPT

在Java虚拟机中,垃圾回收器不仅仅只有一种,什么情况下该使用哪种,对性能又有什么样的影响,这都是我们需要了解的。

串行垃圾回收器

并行垃圾回收器

CMS回收器(主流)

G1回收器 (分区)

 

串行回收器

串行回收器是指使用单线程进行垃圾回收的回收器。每次回收时,串行回收器只有一个工作线程,对于并行能力较弱的计算机来说,串行回收器的专注性和独占性往往有更好的性能表现。串行回收器可以在新生代和老年代使用,根据作用于不同的堆空间,分为新生代串行回收器和老年代串行回收器使用-XX:+UseSeriaIGC参数可以设置使用新生代串行回收器和老年代串行回收器

 

并行回收器(ParNew回收器)

并行回收器在串行回收器基础上做了改进,他可以使用多个线程同时进行垃圾回收,对于计算能力强的计算机而言,可以有效的缩短垃回收所需的实际时间。

ParNew回收器是一个工作在新生代的垃圾收集器,他只是简单的将串行回收器多线程化,他的回收策略和算法和串行回收器一样。

使用-XX:+UseParNewGC新生代ParNew回收器,老年代则使用串行回收器ParNew回收器工作时的线程数量,可以使用-XX: ParallelGCThreads参数指定,一般最好和计算机的CPU相当,避免过多的线程影响性能。

 

并行回收器(ParallelGC回收器)

新生代ParallelGC回收器,使用了复制算法的收集器,也是多践程独占形式的收集器,但 ParallelGC回收器有个非常重要的特点,就是他非常关注系统的吞吐量,

提供了两个非常关键的参数控制系统的吞吐量

-XX: MaxGCPauseMillis:设置最大垃圾收集停顿时间,可用把虚拟机在GC停顿的时间控制在MaxGCPauseMillis范围内,如果希望减少GC停顿时间可以将MaxGCPauseMillis设置的很小,但是会导致GC频繁,从而增加了GC的总时间,降低了吞吐量。所以需要根据实际情况设置该值。

-XX: GCTimeRatio:设置吞吐量大小,它是一个0到100之间的整数,默认情况下他的取值是99,那么系统将花费不超过1/(1+n)的时间用于垃圾回收,也就是1/(1+99)=1%的时间。

另外还可以指定-XX:+ UseAdaptiveSizePolicy打开自适应模式,在这种模式下,新生代的大小、eden、from/to的比例,以及晋升老年代的对象年龄参数会被自动调整,以达到在堆大小、吞吐量和停顿时间之间的平衡点。

 

并行回收器(ParallelOldGC回收器)

老年代ParallelOldGC回收器也是一种多线程的回收器,和新生代的ParallelGC回收器一样,也是一种关注吞吐量的回收器,他使用了标记压缩算法进行实现。

-XX:+UseParallelOldGC进行设置

-XX:+ParallelGCThreads也可以设置垃圾收集时的线程数量

 

CMS回收器

CMS全称为:Concurrent Mark Sweep意为并发标记清除,他使用的是标记清除法,主要关注系统停顿时间。

使用-XX:+UseConcMarkSweepGC进行设置 即可以使用CMS

使用-XX:ConcGCThreads设置并发线程数量。

CMS并不是独占的回收器,也就说CMS回收的过程中,应用程序仍然在不停的工作,又会有新的垃圾不断的产生,所以在使用CMS的过程中应该确保应用程序的内存可用,CMS不会等到应用程序饱和的时候才去回收垃圾,而是在某一阔值的时候开始回收,回收阀值可用指定的参数进行配置,-XX:CMSInitiatingOccupancyFraction来指定,默认为68,也就是说当老年代的空间使用率达到68%的时候,会执行CMS回收,如果内存使用率增长的很快,在CMS执行的过程中,已经出现了内存不足的情况,此时CMS回收就会失败,虚拟机将启动老年代串行回收器进行垃圾回收,这会导致应用程序中断,知道垃圾回收完成后才会正常工作,这个过程GC的停顿时间可能较长,所以-XX: CMSInitiatingOccupancyFraction的设置要根据实际的情况。

之前我们在学习算法的时候说过,标记清除法有个缺点就是存在内存碎片的问题,那么CMS有个参数设置XX:+UseCMSCompactAtFullCollecion可以使CMS回收完成之后进行一次碎片整理,-XX:CMSFULLGCsBeforeCompaction参数可以设置进行多少次CMS回收之后,对内存进行一次压缩

 

G1回收器

G1回收器(Garbage-First)是在jdk1.7中提出的垃极回收器,从长期目标来看是为了取代CMS回收器,G1回收器拥有独特的垃级回收策略,G1属于分代垃圾回收器,区分新生代和老年代,依然有eden和 from/to区,它并不要求整个eden区或者新生代、老年代的空间都连续,它使用了分区算法。

并行性:G1回收期间可多线程问时工作

并发性:G1拥有与应用程序交替执行能力,部分工作可与应用程序同时执行,在整个GC期间不会完全阻塞应用程序。

分代GC:G1依然是一个分代的收集器,但是它是兼顾新生代和老年代一起工作,之前的垃圾收集器他们或者在新生代工作,或者在老年代工作,因此这是一个很大的不同。

空间整理:G1在回收过程中,不会像CMS那样在若干次GC后需要进行碎片整理,G1采用了有效复制对象的方式,减少空间碎片。

可预见性:由于分区的原因,G1可以只选取部分区域进行回收,缩小了回收的范围提升了性能。

使用-XX:+UseG1GC应用G1收集器,

使用-XX: MaxGCPauseMillis指定最大停顿时间

使用- XX: ParallelGCThreads设置并行回收的线程数量

 

Tomcat性能测试:

测试网站吞吐量(1个指标、停顿时间,内存的使用情况,包括回收的效率…)

QPS:Queries Per Second意思是“每秒查询率”,是一台服务器每秒能够相应的查询次数,是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准。

工具:Apache JMeter

实验原理:

通过JMeter对 Tomcat增加压力,不同的虚拟机参数应该会有不同的表现.观察不同配置参数对吞吐量的影响.

-XX:+HeapDumpOnOutOfMemoryError 然后查看吞吐量 -Xloggc: d:/gc.log

测试串行回收器/ParNew回收器/ParallelOldGC回收器、扩大对内存以提升系统性能、调整初始堆大小

JConsole是JDK自带的图形化性能监控工具,通过JConsole可以查看JAVA的应用程序运行概况,可以监控堆信息、永久区使用情况、类加较情况等
实际项目中性能配置在tomcat根目录下conf/catalina.propertise文件里配置。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值