zl程序教程

您现在的位置是:首页 >  后端

当前栏目

JVM_05 垃圾回收制(GC调优)

JVM 调优 垃圾 05 回收 GC
2023-09-11 14:17:55 时间

GC 调优

预备知识:

在这里插入图片描述

  • 查看虚拟机参数命令:
"C:\Program Files\Java\jdk1.8.0_201\bin\java" -XX:+PrintFlagsFinal -version | findstr "GC"

在这里插入图片描述

D:\Note\笔记\JDK源码学习\IDEA-workspace\jdk8>"C:\Program Files\Java\jdk1.8.0_201\bin\java" -XX:+PrintFlagsFinal -version | findstr "GC"
    uintx AdaptiveSizeMajorGCDecayTimeScale         = 10                                  {product}
    uintx AutoGCSelectPauseMillis                   = 5000                                {product}
     bool BindGCTaskThreadsToCPUs                   = false                               {product}
    uintx CMSFullGCsBeforeCompaction                = 0                                   {product}
    uintx ConcGCThreads                             = 0                                   {product}
     bool DisableExplicitGC                         = false                               {product}
     bool ExplicitGCInvokesConcurrent               = false                               {product}
     bool ExplicitGCInvokesConcurrentAndUnloadsClasses  = false                               {product}
    uintx G1MixedGCCountTarget                      = 8                                   {product}
    uintx GCDrainStackTargetSize                    = 64                                  {product}
    uintx GCHeapFreeLimit                           = 2                                   {product}
    uintx GCLockerEdenExpansionPercent              = 5                                   {product}
     bool GCLockerInvokesConcurrent                 = false                               {product}
    uintx GCLogFileSize                             = 8192                                {product}
    uintx GCPauseIntervalMillis                     = 0                                   {product}
    uintx GCTaskTimeStampEntries                    = 200                                 {product}
    uintx GCTimeLimit                               = 98                                  {product}
    uintx GCTimeRatio                               = 99                                  {product}
     bool HeapDumpAfterFullGC                       = false                               {manageable}
     bool HeapDumpBeforeFullGC                      = false                               {manageable}
    uintx HeapSizePerGCThread                       = 87241520                            {product}
    uintx MaxGCMinorPauseMillis                     = 4294967295                          {product}
    uintx MaxGCPauseMillis                          = 4294967295                          {product}
    uintx NumberOfGCLogFiles                        = 0                                   {product}
     intx ParGCArrayScanChunk                       = 50                                  {product}
    uintx ParGCDesiredObjsFromOverflowList          = 20                                  {product}
     bool ParGCTrimOverflow                         = true                                {product}
     bool ParGCUseLocalOverflow                     = false                               {product}
    uintx ParallelGCBufferWastePct                  = 10                                  {product}
    uintx ParallelGCThreads                         = 8                                   {product}
     bool ParallelGCVerbose                         = false                               {product}
     bool PrintClassHistogramAfterFullGC            = false                               {manageable}
     bool PrintClassHistogramBeforeFullGC           = false                               {manageable}
     bool PrintGC                                   = false                               {manageable}
     bool PrintGCApplicationConcurrentTime          = false                               {product}
     bool PrintGCApplicationStoppedTime             = false                               {product}
     bool PrintGCCause                              = true                                {product}
     bool PrintGCDateStamps                         = false                               {manageable}
     bool PrintGCDetails                            = false                               {manageable}
     bool PrintGCID                                 = false                               {manageable}
     bool PrintGCTaskTimeStamps                     = false                               {product}
     bool PrintGCTimeStamps                         = false                               {manageable}
     bool PrintHeapAtGC                             = false                               {product rw}
     bool PrintHeapAtGCExtended                     = false                               {product rw}
     bool PrintJNIGCStalls                          = false                               {product}
     bool PrintParallelOldGCPhaseTimes              = false                               {product}
     bool PrintReferenceGC                          = false                               {product}
     bool ScavengeBeforeFullGC                      = true                                {product}
     bool TraceDynamicGCThreads                     = false                               {product}
     bool TraceParallelOldGCTasks                   = false                               {product}
     bool UseAdaptiveGCBoundary                     = false                               {product}
     bool UseAdaptiveSizeDecayMajorGCCost           = true                                {product}
     bool UseAdaptiveSizePolicyWithSystemGC         = false                               {product}
     bool UseAutoGCSelectPolicy                     = false                               {product}
     bool UseConcMarkSweepGC                        = false                               {product}
     bool UseDynamicNumberOfGCThreads               = false                               {product}
     bool UseG1GC                                   = false                               {product}
     bool UseGCLogFileRotation                      = false                               {product}
     bool UseGCOverheadLimit                        = true                                {product}
     bool UseGCTaskAffinity                         = false                               {product}
     bool UseMaximumCompactionOnSystemGC            = true                                {product}
     bool UseParNewGC                               = false                               {product}
     bool UseParallelGC                            := true                                {product}
     bool UseParallelOldGC                          = true                                {product}
java version "1.8.0_201"
Java(TM) SE Runtime Environment (build 1.8.0_201-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.201-b09, mixed mode)
     bool UseSerialGC                               = false                               {product}
  • 可以根据参数去查询具体的信息:

在这里插入图片描述


1. 调优领域

  • 内存
  • 锁竞争
  • CPU占用
  • IO
  • GC

2. 确定目标

低延迟/高吞吐量? 选择合适的GC

  • CMS G1 ZGC
  • ParallelGC
  • Zing

3. 最快的GC是不发生GC

首先排除减少因为自身编写的代码而引发的内存问题:

  • 查看Full GC前后的内存占用,考虑以下几个问题:
    • 数据是不是太多?
      • resultSet = statement.executeQuery("select * from 大表");
    • 数据表示是否太臃肿?
      • 对象图
      • 对象大小,Java中new一个Object或者包装类型对象,至少16字节。
    • 是否存在内存泄漏?
      • static Map map = HashMap(),当我们不断的向静态的map中新增对象且不移除,就可能造成内存吃紧。
      • 可以使用软引用,弱引用来解决上面的问题,因为它们可以在内存吃紧时,被定期回收。也可以使用第三方的缓存中间件来存储上面的map中的数据。

4. 新生代调优

  • 新生代的特点:
    • 当我们new一个对象时,会先在伊甸园中进行分配,所有的new操作分配内存都是非常廉价且速度极快的
      • TLAB(Thread-Location Allocation Buffer):当我们new一个对象时,会先检查TLAB缓冲区中是否有可用内存,如果有则优先在TLAB中进行对象分配。
    • 死亡对象回收的代价为零
    • 大部分对象用过即死(朝生夕死)
    • MInor GC 所用时间远小于Full GC
  • 新生代内存越大越好么?
    • 不是:
      • 新生代内存太小:频繁触发Minor GC,会 STW,会使得吞吐量下降。
      • 新生代内存太大:老年代内存占比有所降低,会更频繁地触发Full GC。而且触发Minor GC时,清理新生代所花费的时间会更长。
    • 新生代内存设置为能容纳 并发量*(请求-响应) 的数据为宜。

在这里插入图片描述


5. 幸存区调优

  • 幸存区最大能够保存 当前活跃对象+需要晋升的对象
  • 晋升阈值配置得当,让长时间存活的对象尽快晋升。

6. 老年代调优

以CMS为例:

  • CMS的老年代内存越大越好。
  • 先尝试不做调优,如果没有 Full GC 那么说明当前系统暂时不需要优化,否则,就先尝试调优新生代。
  • 观察发生Full GC 时老年代的内存占用,将老年代内存预设调大 1/4 ~ 1/3
    • -XX:CMSInitiatingOccupancyFraction=percent

7. 案例

  • 当Full GC 和 Minor GC 调用频繁。
  • 当请求高峰期发生Full GC,单次暂停时间特别长(CMS)
  • 在老年代充裕的情况下,发生Full GC (1.7)

上面集中情况都是需要调优的!