垃圾回收gc

1 篇文章 0 订阅

常用gc工具-----jvisualvm

安装visual gc插件

几张gc图感知认识

 

g1gc相关

 

G1垃圾收集器的设计原则是“首先收集尽可能多的垃圾(Garbage First)”,目标是为了尽量缩短处理超大堆(超过4GB)产生的停顿。

因此,G1并不会等内存耗尽(比如Serial 串行收集器、Parallel并行收集器 )者快耗尽(CMS)的时候才开始垃圾回收,而是在内部采用了启发式算法,在老年代中找出具有高收集收益的分区(Region)进行收集。

同时 G1 可以根据用户设置的STW(Stop-The-World)停顿时间目标(响应时间优先)自动调整年轻代和总堆的大小,停顿时间越短年轻代空间就可能越小,总堆空间越大。

G1相对于CMS一个比较明显的优势是,内存碎片的产生率大大降低。

G1在 JDK7u4以上都可以使用,在JDK9开始,G1为默认的垃圾收集器,以替代CMS

 

G1的特性

  • 面向服务端应用的垃圾收集器
  • 并行与并发:G1能充分利用多CPU、多核环境使用多个CPU或CPU核心来缩短STW(Stop-The-World)停顿时间。
  • 分代收集:G1物理上不分代,但逻辑上仍然有分代的概念。
  • 空间整合:不会产生内存空间碎片,收集后可提供规整的可用内存,整理空闲空间更快。
  • 可预测的停顿(它可以有计划的避免在整个JAVA堆中进行全区域的垃圾收集)
  • 适用于不需要实现很高吞吐量的场景
  • JAVA堆内存布局与其它收集器存在很大差别,它将整个JAVA堆划分为多个大小相等的独立区域或分区(Region)。
  • G1收集器中,虚拟机使用Remembered Set来避免全堆扫描。

 

一. 名词解释及相关概念

  • MetaSpace
    在Java8之后取代永久代方法区的内存部分,NativeMemory

  • Mixed GC Event
    所有Young Region和一部分Old Region的混合GC时间。

  • Reclaimable
    G1 为了能够回收,创建了一系列专门用于对象回收的Region,存放在链表中,只包含存活率小于-XX:G1MixedGCLIveThresholdPercent(默认是85%)的region, region的值除以整个Java堆区,如果大于-XX:G1HeapWastePercent(默认5%),则启动回收机制

  • RSet(Remember Set)
    用于跟踪对于Region内对象的引用,外部Region到Region内部。占整个堆区的5%。

  • CSet(Collection Set)
    收集集合。保存一次GC中即将进行GC的Region。占整个堆区的1%。

  • Root Region Scan
    从RS(根区间)开始的扫描,标记所有可达对象。

  • Evacution Failure
    Promotion Failure对象内存分配失败。

  • Top-at-matk-start(TAMS)
    每个Region中的两个内存指针。在TAMS之上的是新分配的对象。prevTAMS、nextTAMS

  • PLAB(Promoiton Local Allocation Buffers)
    避免多线程竞争相同的数据,每个线程具有PLAB,针对Survior和Old区域,用于年轻代的回收。

  • TLAB(Thead Local Allocation Buffers)
    线程本地分配内存。对于每个线程分配专门的一块Eden区域,在G1中是Region。

  • Root Set(根集合)
    每个线程栈中,里面的对象引用和引用指向的对象。

  • 对象存活判断

  1. 引用计数。无法判断循环引用的对象。
  2. 可达性分析。一个对象到GC Roots没有链接时认为是不可达对象。
  3. GCRoots.虚拟机栈引用的对象;方法区中类静态属性实体引用的对象;方法区中常量引用的对象;本地方法栈中JNI引用的对象
  • Minor GC
    年轻代GC

  • Major GC(Full GC)
    发生在老年代的GC

  • 对象提升规则

  1. 对象优先分配在Eden区,Eden区满时进行一次Minor GC。
  2. 大对象直接进入老年代中,在G1中对于大于Region大小45%的对象认定为大对象。
  3. 长期存活的对象进入老年代。对象进行一次MinorGC后进入到Survior区,之后每进行一次MinorGC对象年龄加1。对于大于阈值的对象进入到老年代,Threshold默认值为15。
  4. 对象年龄动态判断。Survior区中相同年龄的对象大小的总和大于Survior大小的一半时,大于等于该年龄的对象进入到老年代。
  5. 空间分配担保。进行MinorGC时,JVM会计算survior区域移到老年代区域对象的平均大小,如果这个值大于老年代的剩余大小则进行一次FullGC,之后检查HandlePromotionFauilue逻辑,True只进行MinorGC
  • Full GC 触发条件
  1. 老年代空间不足
  2. 永久代空间满OOM:PermGen Space(Java8 之前)
  3. CMS GC时出现Promotion Faield和Concurrent Model Failure
  4. 统计到升到老年代的对象的大小大大于老年代剩余的空间大小

 

 

g1的目标是控制停顿时间即stw,那么肯定有阶段是stw的,初始标记,重新标记,清理

Phases of the Marking Cycle

The marking cycle has the following phases:

  • Initial mark phase: The G1 GC marks the roots during this phase. This phase is piggybacked on a normal (STW) young garbage collection.
  • Root region scanning phase: The G1 GC scans survivor regions of the initial mark for references to the old generation and marks the referenced objects. This phase runs concurrently with the application (not STW) and must complete before the next STW young garbage collection can start.
  • Concurrent marking phase: The G1 GC finds reachable (live) objects across the entire heap. This phase happens concurrently with the application, and can be interrupted by STW young garbage collections.
  • Remark phase: This phase is STW collection and helps the completion of the marking cycle. G1 GC drains SATB buffers, traces unvisited live objects, and performs reference processing.
  • Cleanup phase: In this final phase, the G1 GC performs the STW operations of accounting and RSet scrubbing. During accounting, the G1 GC identifies completely free regions and mixed garbage collection candidates. The cleanup phase is partly concurrent when it resets and returns the empty regions to the free list.

 

二.G1 Heap Allocation

In reality, these regions are mapped into logical representations of Eden, Survivor, and old generation spaces.

 

g1gc 相关参数

选项/默认值说明
-XX:+UseG1GC使用 G1 (Garbage First) 垃圾收集器
-XX:MaxGCPauseMillis=n设置最大GC停顿时间(GC pause time)指标(target). 这是一个软性指标(soft goal), JVM 会尽量去达成这个目标.
-XX:InitiatingHeapOccupancyPercent=n启动并发GC周期时的堆内存占用百分比. G1之类的垃圾收集器用它来触发并发GC周期,基于整个堆的使用率,而不只是某一代内存的使用比. 值为 0 则表示"一直执行GC循环". 默认值为 45.
-XX:NewRatio=n新生代与老生代(new/old generation)的大小比例(Ratio). 默认值为 2.
-XX:SurvivorRatio=neden/survivor 空间大小的比例(Ratio). 默认值为 8.
-XX:MaxTenuringThreshold=n提升年老代的最大临界值(tenuring threshold). 默认值为 15.
-XX:ParallelGCThreads=n设置垃圾收集器在并行阶段使用的线程数,默认值随JVM运行的平台不同而不同.
-XX:ConcGCThreads=n并发垃圾收集器使用的线程数量. 默认值随JVM运行的平台不同而不同.
-XX:G1ReservePercent=n设置堆内存保留为假天花板的总量,以降低提升失败的可能性. 默认值是 10.
-XX:G1HeapRegionSize=n使用G1时Java堆会被分为大小统一的的区(region)。此参数可以指定每个heap区的大小. 默认值将根据 heap size 算出最优解. 最小值为 1Mb, 最大值为 32Mb.

  • -XX:G1HeapRegionSize=n

    Sets the size of a G1 region. The value will be a power of two and can range from 1MB to 32MB. The goal is to have around 2048 regions based on the minimum Java heap size.

  • -XX:MaxGCPauseMillis=200

    Sets a target value for desired maximum pause time. The default value is 200 milliseconds. The specified value does not adapt to your heap size.

  • -XX:G1NewSizePercent=5

    Sets the percentage of the heap to use as the minimum for the young generation size. The default value is 5 percent of your Java heap. This is an experimental flag. See "How to unlock experimental VM flags" for an example. This setting replaces the -XX:DefaultMinNewGenPercent setting. This setting is not available in Java HotSpot VM, build 23.

  • -XX:G1MaxNewSizePercent=60

    Sets the percentage of the heap size to use as the maximum for young generation size. The default value is 60 percent of your Java heap. This is an experimental flag. See "How to unlock experimental VM flags" for an example. This setting replaces the -XX:DefaultMaxNewGenPercent setting. This setting is not available in Java HotSpot VM, build 23.

  • -XX:ParallelGCThreads=n

    Sets the value of the STW worker threads. Sets the value of n to the number of logical processors. The value of n is the same as the number of logical processors up to a value of 8.

    If there are more than eight logical processors, sets the value of n to approximately 5/8 of the logical processors. This works in most cases except for larger SPARC systems where the value of n can be approximately 5/16 of the logical processors.

  • -XX:ConcGCThreads=n

    Sets the number of parallel marking threads. Sets n to approximately 1/4 of the number of parallel garbage collection threads (ParallelGCThreads).

  • -XX:InitiatingHeapOccupancyPercent=45

    Sets the Java heap occupancy threshold that triggers a marking cycle. The default occupancy is 45 percent of the entire Java heap.

  • -XX:G1MixedGCLiveThresholdPercent=65

    Sets the occupancy threshold for an old region to be included in a mixed garbage collection cycle. The default occupancy is 65 percent. This is an experimental flag. See "How to unlock experimental VM flags" for an example. This setting replaces the -XX:G1OldCSetRegionLiveThresholdPercent setting. This setting is not available in Java HotSpot VM, build 23.

  • -XX:G1HeapWastePercent=10

    Sets the percentage of heap that you are willing to waste. The Java HotSpot VM does not initiate the mixed garbage collection cycle when the reclaimable percentage is less than the heap waste percentage. The default is 10 percent. This setting is not available in Java HotSpot VM, build 23.

  • -XX:G1MixedGCCountTarget=8

    Sets the target number of mixed garbage collections after a marking cycle to collect old regions with at most G1MixedGCLIveThresholdPercent live data. The default is 8 mixed garbage collections. The goal for mixed collections is to be within this target number. This setting is not available in Java HotSpot VM, build 23.

  • -XX:G1OldCSetRegionThresholdPercent=10

    Sets an upper limit on the number of old regions to be collected during a mixed garbage collection cycle. The default is 10 percent of the Java heap. This setting is not available in Java HotSpot VM, build 23.

  • -XX:G1ReservePercent=10

    Sets the percentage of reserve memory to keep free so as to reduce the risk of to-space overflows. The default is 10 percent. When you increase or decrease the percentage, make sure to adjust the total Java heap by the same amount. This setting is not available in Java HotSpot VM, build 23.

简单调优经历,说明对g1的感知

环境:java8

项目背景:企业短信业务,特点:并发大,单条处理快,包含验证码等业务,单条处理的时间不能过长

由于java8默认垃圾回收并不是g1,在原有的垃圾回收下,经常会发现卡顿现象【日志中发现】,大部分都是在毫秒级别处理,但是很规律的隔一小段时间就会出现1条2秒多左右的服务,考虑是垃圾回收导致,将原有的垃圾回收器更换为g1,能够观察到高延迟处理的单条信息不再出现。考虑g1在控制时延方面可能有更好的优化方案

 

附:arthas工具实时监控jvm

 

 

相关官方文档:

java8

https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/index.html

g1gc相关

https://www.oracle.com/technetwork/tutorials/tutorials-1876574.html

https://www.oracle.com/technical-resources/articles/java/g1gc.html

 

早期文档

https://www.oracle.com/java/technologies/javase/gc-tuning-6.html

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值