首页 > 编程知识 正文

说一下 jvm 有哪些垃圾回收算法,说一下 jvm 有哪些垃圾回收算法?

时间:2023-05-06 00:38:53 阅读:190102 作者:3510

引用计数法

这是一种经典的旧垃圾回收算法,如果对象被其他引用引用引用,则以计数器1为中心,如果引用无效,则以-1为中心。 但是,这种方式存在非常严重的问题。 无法支持循环参照时,或者每次都进行加减操作会浪费系统的性能。

置标法

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

复制算法(java堆的jwdbks代from和to区域) )。

其核心思想是,将内存空间分为2个块,每次只使用其中的1个,垃圾回收时,将使用中的内存中残留的对象复制到未使用的内存中,然后,点击以前使用过的内存块的所有对象

标记压缩法(java堆年代) ) ) ) ) )。

标签压缩法在标签消除法中得到了优化,将生存的对象压缩到存储器侧后进行GC。

分代算法

就是根据对象的特征把内存分成n个块,根据每个内存的特征使用不同的算法。 对于jwdbks世代和老世代来说,jwdbks世代的回收频率高,但每次回收时间短,老世代的回收频率低,但时间会变长,所以应该尽量减少老世代的GC。

分区算法(jdk1.7后G1 ) )。

其主要内容是将整个内存划分为n个小的独立空间,每个空间都可以独立使用。 这样可以精细控制一次重用几个小空间,而不是对整个空间进行GC,从而提高性能,缩短GC的停止时间。

jwdbks代的from和to区域使用复制算法,而较老的年代使用标记压缩算法。

对象如何进入古老的年代?

一般对象的创建被放置在eden区域,GC后的每个年龄1达到阈值时,被放置在旧年代。

-XX:MaxTenuringThreshold设置,默认值为15

特殊:对于大型对象,如果jwdbks层代无法加载,则可以直接进入旧年代并设置此大小

-XX:PretenureSizeThreshold

虚拟机会为较小的对象优先分配TLAB空间中的数据,因此失去了在旧年代分配的机会

使用-XX:-UseTLAB禁用TLAB区域

下图是创建java对象时的内存选择过程。

TLAB

全名是Thread Local Allocation Buffer,即线程的本地分配高速缓存,从名字来看是线程专用的内存分配区域,是为了使对象分配高速化而生成的,每个线程都是tlalas JVM使用此TLAB区域来避免多线程冲突问题,并提高对象分配的效率。 TLAB空间一般不大,如果大型对象未分配给TLAB,则会直接分配给堆。

- xx :用户实验室使用实验室

-XX: TLABSize配置大小

- xx : tlabrefillwasterfraction设置保留进入tlab空间的各个对象的大小。 这是比例值,默认为64。 这意味着如果对象大于整个空间的1/64,则会在堆中创建对象。

-XX: PrintTLAB显示TLAB信息

-XX:ResizeTLAB自调整阈值

垃圾收集器

垃圾回收器(jwdbks世代和旧年代) ) ) )。

-XX: UseSerialGC是串行还是并行,取决于服务器性能

Parallel Scavenge垃圾收集器(jwdbks世代) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) )。

- xx : useparallelgc on-xx : parallelgcthreads指定线程数,通常与CPU内核数相同。

使用复制算法有一个非常重要的特征关注系统吞吐量,它提供了以下两个参数控制:

-XX:MaxGCPauseMillis设定了最大垃圾收集停止时间,可以将JVM在GC停止的时间控制在这个范围内,设定变小了

虽然可以减少GC暂停时间,但是GC频繁发生,GC总时间增加,吞吐量下降。

-XX:GCTimeRatio将吞吐量大小设置为0-100整数,默认值为99,系统在GC上花费1/(1 n,即1/199=1% )的时间。

此外,-XX: UseAdaptiveSizePolicy将打开自适应模式。 此模式自动调整jwdbks层代大小、eden、from/to比例和其他参数,以平衡堆大小、吞吐量和停止时间。

-XX: UseParallelOldGC配置旧年代的GC并使用标记压缩算法。 -设置xx :并行lgcthreads线程数

CMS回收器

Concurrent Mark Sweep使用主要关注系统停机时间的标签消除法同时进行标签消除

-XX:UseConcMarkSweepGC打开,设置-XX:ConcGCThreads线程数

CMS不是独占的垃圾收集器,在工作中程序也在不断运行,垃圾也在不断产生,使用CMS时必须保证足够的内存。 在APP应用程序饱和之前,CMS不会运行,而是在某个阈值时开始回收。 可以用一个参数指定。 - xx : cmsinitiatingoccupancyfracti

on,默认值为68,意思是当老年代空间使用率达到68%的时候执行。如果内存使用率增长过快,CMS没有足够的内存去执行,这时候CMS会中断,JVM会启用老年代串行回收器,但是会导致程序中断,直到回收完成后才会正常工作,这个过程GC的停顿时间可能会很长,所以这个参数要根据实际情况来设置。
解决标记清除法的碎片问题,使用-XX:+UseCMSCompactAtFullCollection使CMS完成后整理碎片,-XX:CMSFullGCsBeforeCompaction设置多少次回收后整理碎片。
注意:CMS无法与Parallel Scavenge收集器一起工作,只能选择ParNew或者Serial收集器。

★G1回收器
Garbage-First 是在JDK7之后提出的,长远目标是取代CMS,属于分代垃圾回收器,区分jwdbks代和老年代,依然有eden、from、to区,并不要求这些区域的内存空间连续,使用的算法是分区算法。
并行性:回收期间多线程同时工作。
并发性:与应用程序执行不会发生阻塞。
分代GC:依然是一个分代GC垃圾回收器,但是它兼顾jwdbks代和老年代一起工作,之前的垃圾回收器只工作在jwdbks代或者老年代。
空间整理:不会像CMS在若干次GC后需要进行碎片整理,G1采用有效复制对象的方式减少空间碎片。
可预见性:由于分区的原因,G1可以只选取部分区域进行回收,缩小了回收的范围,提升了性能。
-XX:+UseG1GC 开启
-XX:MaxGCPauseMillis 最大停顿时间
-XX:ParallelGCThreads 线程数

-Xloggc:d:/gc.log gc的log存放位置

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。