java 垃圾回收

本文深入探讨了Java垃圾回收机制,重点介绍了Oracle HotSpot JVM中的分代收集算法,包括Young、Old和Permanent区。讨论了不同的垃圾收集器,如Throughput、CMS和G1,分析了它们的优缺点及适用场景。CMS收集器强调最短停顿时间,而G1则旨在处理大堆时减少停顿。文章还提到了GC参数调整,如堆大小、新老年代比例和并发线程数等,为实际应用中的GC调优提供了指导。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文基于Oracle hotspot jvm


1.GC:查找不再使用的对象,以及释放这些对象所管理的内存

2.算法:分代收集


Young:主要是用来存放新生的对象。

Old:主要存放应用程序中生命周期长的内存对象。

Permanent:是指内存的永久保存区域,主要存放ClassMeta的信息,Class在被 Load的时候被放入PermGen 

在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。而老年代中因为对象存活率高、没有额外空间对它进行分配担保,就必须使用“标记-清理”或“标记-整理”算法来进行回收。


3.主流收集器:

   

   Serial
   Throughput(Parallel):Parallel新生代+ParallelOld老年代
   CMS(Concurrent mark sweep ):ParaNew新生代 +CMS老年代
   G1(GarbageFirst)
   备注:

          2.Throughput minorfullgc时空停顿、

          3.Cmsminor时空停顿 fullgc时仅在部分阶段存在  (初始标记,重新标记)


 Serial :
      串行收集器是最古老,最稳定以及效率高的收集器,可能会产生较长的停顿,只使用一个线程去回收。新生代、        老年代使用串行回收;新生代复制算法、老年代标记-压缩;垃圾收集的过程中会StopThe World(服务暂停)
          参数控制:-XX:+UseSerialGC  串行收集器
 Parallel:
     Parallel Scavenge收集器类似ParNew收集器,Parallel收集器更关注系统的吞吐量新生代复制算法多线程来进行年轻代的垃圾收集、老年代串行标记-压缩
  参数控制:-XX:+UseParallelGC  使用Parallel收集器+老年代串行
ParallelOld
  Parallel OldParallelScavenge收集器的老年代版本,使用多线程和“标记-整理”算法。这个收集器是在JDK1.6中才开始提供,和ParallelGC一样。不同之处,ParallelOld GC在年轻代垃圾收集和年老代垃圾回收时都使用多线程收集。
  参数控制: -XX:+UseParallelOldGC 使用Parallel收集器+老年代并行
ParNew:
  ParNew收集器其实就是Serial收集器的多线程版本。新生代并行,老年代串行;新生代复制算法、老年代标记-压缩(应用程序暂停)
        参数控制:-XX:+UseParNewGC  ParNew收集器

                         -XX:ParallelGCThreads 限制线程数量

CMS:

         CMSConcurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。Fullgc时不再暂停应用线程,使用若干后台线程定期对老年代空间扫描回收(标记-清除),消除在fullgc时的长时间停顿。(minorgc还是暂停所有应用线程


         

参数控制:-XX:+UseConcMarkSweepGC 

                         -   XX:+UseParNewGC

G1:

       G1缩短处理大堆(>4GB)时产生的停顿,采用将堆分成若干区域,新生代仍采用暂停所有应用线程的方式,多线程将存活对象移动到Survivor或老年代,老年代由后台线程完成,大多数的工作不需要暂停应用线程。(标记-压缩)

  参数控制: -XX:+UseG1GC(默认关闭)

4.GC选择  

1.Throughput处理应用程序线程的批量任务能最大程度的利用cpu的处理能力,通常能获得更好的性能

2.如果批量任务并没有使用机器上所有可用cpu资源,此时Concurrent收集器能获得更好的性能

3.通常情况下,throughput是收集器的平均响应时间比concurrent要差,但是在90%响应时间或者99%响应时间指标上,throughput要比concurrent好一些

4.使用throughput会超负荷的进行大量fullgc时,切换concurrent能获得更低的响应时间

依据:主要是有多少空闲的cpu用于后台的并发线程

结论:

  ¨批量任务:cpu多而且有剩余选concurrent,否则throughput

  ¨吞吐量:存在空闲cpuCMS,否则throughput

  ¨堆大小:在使用Concurrent时,若堆较小CMS,否则G1

5.GC调优

  

¨调整堆大小:

      –Xms,-Xmx(Fullgc后释放70%空间)

¨代空间调整新生代:

      -XX:NewRatio,-XX:NewSize=N,                   

      -XX:MaxNewSize=N

¨永久代和元空间调整:

      –XX:PermSize=N,-XX:MaxPermSize=N,

      -XX:MetaspaceSize=N, 

      - XX:MaxMetaspaceSize=N

¨控制并发:

      –XX:ParallelGCThreads=N

¨自适应调整:

     –XX:-UseAdaptiveSizePolicy

6.CMS调优

  

¨并发失效:CMS不能够以足够快的速度清理老年代空间,新生代需要进行垃圾回收时,cms收集器发现老年代没有足够的空间容纳这些晋升对象不得不对老年代进行垃圾回收(发生fullgc)
¨优化途径:

     1.调整堆大小增加老年代空间

     2.提高后台线程运行频率 设置老年代空间占用达到

         N时启动并发周期

        –xx:CMSInitiatingOccupancyFaction=N,

        -xx:UseCMSInitiatingOccupancyOnly=true

     3.调整后台线程 –xx:ConcGCThreads=N

     4.增量式cms(java8已不推荐)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值