java-jvm-4-gc

125 阅读5分钟

GC

garbage collector

jdk8-gc

jdk默认的垃圾回收器查看..默认的其实有时候是最好的.

# 设置jvm参数Heap最大值 -XX:MaxHeapSize=
# 查看java默认的分配的大小,通过参数-XX:+PrintFlagsFinal  或者 -XX:+PrintCommandLineFlags 查找

> java [-XX:+PrintCommandLineFlags|-XX:+PrintFlagsFinal] -version

# 1. jdk8
## >java -XX:+PrintCommandLineFlags -version
-XX:InitialHeapSize=502370240
-XX:MaxHeapSize=8037923840 
-XX:+PrintCommandLineFlags 
-XX:+UseCompressedClassPointers
-XX:+UseCompressedOops
-XX:+UseParallelGC

### YG,OG使用不同组合的算法
### 一般业务场景使用的CMS,需要单打独配置,应为CMS部署JDk自带的GC回收器



# 2. jdk9
## > 
-XX:G1ConcRefinementThreads=4
-XX:GCDrainStackTargetSize=64
-XX:InitialHeapSize=134217728
-XX:MaxHeapSize=2147483648
-XX:+PrintCommandLineFlags 
-XX:ReservedCodeCacheSize=251658240 
-XX:+SegmentedCodeCache 
-XX:+UseCompressedClassPointers 
-XX:+UseCompressedOops 
-XX:+UseG1GC

####### YG,OG都使用G1算法

jdk部分源码

hotpot虚拟机源码,Heap大小(MaxHeapSize=byte)其实是2M的整数倍,用于查看heap的最大值,

# hotpot源码
size_t CollectorPolicy::compute_heap_alignment() {
  // The card marking array and the offset arrays for old generations are
  // committed in os pages as well. Make sure they are entirely full (to
  // avoid partial page problems), e.g. if 512 bytes heap corresponds to 1
  // byte entry and the os page size is 4096, the maximum heap size should
  // be 512*4096 = 2MB aligned.
  // (heap的512byte对应操作系统的一个byte,则系统的
  // 一个page对应一个2M,即Heap大小与2M对齐,是2M的倍数,heap大小=2M*X)
 
  // There is only the GenRemSet in Hotspot and only the GenRemSet::CardTable
  // is supported.
  // Requirements of any new remembered set implementations must be added here.
  size_t alignment = GenRemSet::max_alignment_constraint(GenRemSet::CardTable);
 
  // Parallel GC does its own alignment of the generations to avoid requiring a
  // large page (256M on some platforms) for the permanent generation.  The
  // other collectors should also be updated to do their own alignment and then
  // this use of lcm() should be removed.
  if (UseLargePages && !UseParallelGC) {
      // in presence of large pages we have to make sure that our
      // alignment is large page aware
      alignment = lcm(os::large_page_size(), alignment);
  }
  return alignment;
}
  1. -XX:InitialHeapSize=查看支持的初始堆大小,单位都是byte
  2. -XX:MaxHeapSize=查看jdk支持的最大堆大小,更系统内存有直接关系

UseParallelGC

JDK8默认垃圾回收器

UseParallelGC = Parallel Scavenge(YG) + PS MarkSweep(OG)

gc_list.png

可见...jdk8环境下默认的gc工具是YG使用 Parallel Scavenge(支持高的吞吐),OG使用的Serial Old(其实应该是..PS MarkSweep算法..这是官方的错误...);

YG选择的逻辑可能是为了提高吞吐; 但是OG使用的并发线程,而且可能存在内存碎片.

PS MarkSweep应该是并行标记清除的,内存碎片

算法选择

  • YG:提高吞吐计算,使用Parallel-Scanvenge,并发复制算法,是用空间换时间
  • OG:使用PS MarkSweep,节省STW,并发清楚

Parallel-Scanvenge

Paralell Scanvenge(吞吐量优先的回收器)...适用于新生代,采用标记复制算法、多线程模型进行垃圾收集...

回收器选择考虑因素:吞吐量/STW时间

  1. 吞吐量 = 用户程序运行时间/(用户程序运行时间+GC时间); 主要是CPU密集型的场景。后台/cpu计算多的场景。
  2. STW时间,使用于用户交互多的场景 =>GC时间

主要的参数

-XX:MaxGCPauseMills:最大GC停顿时间(mills),注意不是越小越好,可能频繁YGC -XX:GCTimeRatio:GC时间/总时间比,默认=99,即1/(1+99)默认占1/100...GC的ratio概念都奇怪的... -XX:UseAdaptiveSizePolicy: 使用自适应的参数,不懂用这个就可以了...

PSMarkSweep

Serial old 单线程...标记整理算法..一般作为CMS的备选方案,在Concurrent Mode Failure情况下使用.

PS MarkSweep是以seril Old算法为模版设计.(有些官方使用serial old 代替了PSMarkSweep, JVM虚拟机就是)

补充: Concurrent Mode Failure(并发模式)失败是会发生FullGC...

CMS是适用于OG的GC算法..

  1. CMS触发FGC的可能
  2. CMS内存碎片
  3. CMS的YGC算法吞吐计算不如ps

CMS

CMS: YG使用ParNew, OG使用CMS,是支持出并发的

  • 选择这个能减少STW

jdk9-gc

G1

对比CMS....重要的事情说三遍..。毕竟有人喜欢问为什么

  1. 通过预估模型,可控停顿时间 => STW
  2. 不会产生内存碎片

G1毕竟是设计来替代CMS的,两者都是支持并发,大部分gc阶段是不会挂起用户线程的;不同的主要是上面2点.

设想对于使用大堆(MaxheapSize)的场景,又要求较小的系统STW时间(其实就是现在大型web应用的场景)..G1是目前最好的算法....

gc-g1.png

大神的图就是nb...再谢...

G1将整个堆heap分成多个region; 基于region和预估模型做增量回收...(预估回收region占用的时间不超过配置的时间)

G1有额外的空间占用,2个set集合Remembered Set(有引用的集合)和Collection Sets(需要被回收的集合)。 => 有点像GO的内存模型

  1. 整个堆大约认为2000个region,每个region大小一致2M-32M(2M的倍数是不变的...)
  2. 不同区(YG/OG/MP)的region大小可能不一样的

G1的优势

  • region的引入;主要解决GC碎片化的问题;同时实现JVM(YG/OG)逻辑上是连续空间而不需要物理是连续空间的问题

  • STW时间优化,通过参数配置STW期望时间,并通过预估模型增量回收region

  • -XX:G1HeapRegionSize=n设置region大小,1-32M

  • g1最好使用自适应的配置

  • -XX:GCTimeRatio即为GC与应用的耗费时间比,G1默认为9,而CMS默认为99

jdk11-gc

jdk11引入

ZGC

  1. Pause times do not exceed 10ms
  2. Pause times do not increase with the heap or live-set size
  3. Handle heaps ranging from a few hundred megabytes to multi terabytes in size
  • STW延迟时间<10ms

  • STW不增加heap/live-set大小

  • heap大小支持MB-TB级别

  • 标记、复制、迁移,所有操作并发

  • 只有1代,不分YG、OG

  • 系统内存需要支持numa-aware

pointer coloring

load barriers.

ps