java性能优化之分代回收

 更新时间:2022年07月08日 08:35:11   作者:​ 我犟不过你   ​  
这篇文章主要介绍了java性能优化之分代回收,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下

前言

我们今天一起来聊一聊关于垃圾收集的细节问题。垃圾收集是通过何种方式减少stop the world?这将是垃圾回收的重点内容。

什么是分代回收?

什么是分代回收,初次接触的同学肯定是很懵的。还记得我们前面在介绍使用jvisualvm工具的时候,从它给我们反馈的视图上看到,有几个不同的数据块,且是动态的,如下图红圈的部分:

从左到右分别是:

  • Metaspace :元空间
  • Old :老年代
  • Eden + S0 + S1 : 这三个加在一起称为年轻代

到目前为止,市面上常见的垃圾收集器,都是按照这种分代回收的方式进行垃圾回收的,但是其内部的实现方式却有很大的差别。

本章我们的重点是 老年代 和 年轻代 。

通过上图我们发现,年轻代有三部分组成:

  • Eden :通常称为Eden区,翻译过来也可以称为伊甸园区。
  • S0 和 S1:通常称为survivor区,翻译过来称为幸存者区,由幸存者0和幸存者1所组成。

为什么采用分代回收?

绝大部分的对象,它们的生命周期非常短暂,甚至绝大多数都是临时对象,垃圾收集器的设计需要适应这种情况。

我们都知道对象创建,存放在堆中,而不论是老年代还是年轻代都是堆中的一部分。

年轻代回收

当对象被创建后,会被分配至年轻代,随着对象的增加,年轻代会被占满,此时将会停止全部的应用线程,并进行垃圾回收,没有被使用的对象会被回收,仍然被使用的对象将会被移动到其他的地方。这种操作就是MinorGC,年轻代回收。

使用分代算法的最根本原因,是为了尽量的减少垃圾回收造成的停顿,我们可以从下面两个方面考虑:

  • 新生代是堆的一部分,仅处理一部分空间,一定比整个堆空间的时间要短,停顿时间也就短。但是我们一定会想到,停顿的频率增加了。
  • 年轻代的空间分配方式,对性能有影响。年轻代中,eden占据大部分空间,而S0和S1平分剩余空间。对象首次创建会在Eden中,经过一次垃圾回收时,Eden被清空,未使用的对象被回收,仍然使用的对象进入Survior或老年代。Eden区的清空操作,相当于进行了一次压缩整理

即使是年轻代的回收,仍然存在时空停顿

老年代回收

前面提到,除了在Eden可能将对象移动到老年代当中,对于在Survior当中没有被回收的对象,最终也会移动到老年代当中。当老年代被占满时,会停止所有的应用线程,找到不再使用的对象进行垃圾回收。这个过程将会停顿很长时间,我们称之为Full GC

更加厉害的回收方式

前面的描述其实都是较为简单的垃圾收集器,在停止应用线程后去发现不再使用的对象,进行回收。

然而实际上,通过一些定制,和复杂的计算,我们可以在应用线程运行时去找到不再使用的对象。在前一篇文章一笔带过的CMS和G1收集器,就是如此。他们不需要停止应用线程就可以找到不再使用的对象,所以它们也叫做concurrent垃圾收集器

垃圾在查找的时候将会占用很多时间,当然查找算法将是下一章节我们需要学习的内容。然而concurrent垃圾收集器可以尽可能的减少应用的停顿时间,它们也可以称为低停顿收集器

这种垃圾收集器缩减应用的停顿时间,其代价是占用更多的CPU。即使是G1和CMS也会遇到长时间的Full GC,这将是我们需要针对实际环境调优的方向。

垃圾收集器的权衡

前面简单描述了不同垃圾收集器的垃圾收集方式,以及造成的影响。但是在我们选择垃圾收集器的过程中还是需要一定的权衡,才能使其发挥最佳的性能。

我们需要考虑的重点就是:

  • 吞吐量:如果你的系统需要大批量的处理数据等,换句话说,不要求每次响应时间最快,而平均响应时间更加重要,Parallel收集器也许会有不错的表现。
  • 响应时间:简单来说,如果你想要你的接口获得更快的响应时间,那么concurrent收集器将是更好的选择。
  • CPU性能:使用current收集器势必要消耗更多的CPU资源。

到此这篇关于java性能优化之分代回收的文章就介绍到这了,更多相关java性能优化内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Spring AOP实现Redis缓存数据库查询源码

    Spring AOP实现Redis缓存数据库查询源码

    这篇文章主要介绍了Spring AOP实现Redis缓存数据库查询的相关内容,源码部分还是不错的,需要的朋友可以参考下。
    2017-09-09
  • servlet之web路径问题_动力节点Java学院整理

    servlet之web路径问题_动力节点Java学院整理

    这篇文章主要为大家详细介绍了servlet之web路径问题的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-07-07
  • rabbitmq使用springboot实现direct模式(最新推荐)

    rabbitmq使用springboot实现direct模式(最新推荐)

    这篇文章主要介绍了rabbitmq使用springboot实现direct模式,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-07-07
  • JDBC Template基本使用方法详解

    JDBC Template基本使用方法详解

    这篇文章主要介绍了JDBC Template基本使用方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-06-06
  • Java中的JWT使用详解

    Java中的JWT使用详解

    这篇文章主要介绍了Java中的JWT使用详解,JWT是一个开放标准(rfc7519),它定义了一种紧凑的、自包含的方式,用于在各方之间以JSON对象安全地传输信息,需要的朋友可以参考下
    2023-08-08
  • SpringBoot中定义Bean的方法总结

    SpringBoot中定义Bean的方法总结

    在Spring Boot应用程序中,定义Bean是非常常见的操作,它是构建应用程序的基础,pring Boot提供了多种方式来定义Bean,每种方式都有其适用的场景和优势,本文将介绍Spring Boot中定义Bean的几种常见方式,需要的朋友可以参考下
    2023-12-12
  • Mybatis自关联查询一对多查询的实现示例

    Mybatis自关联查询一对多查询的实现示例

    这篇文章主要介绍了Mybatis自关联查询一对多查询的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-02-02
  • springboot多文件上传实现使用postman测试多文件上传接口

    springboot多文件上传实现使用postman测试多文件上传接口

    这篇文章主要介绍了springboot多文件上传实现使用postman测试多文件上传接口,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • springboot项目使用SchedulingConfigurer实现多个定时任务的案例代码

    springboot项目使用SchedulingConfigurer实现多个定时任务的案例代码

    这篇文章主要介绍了springboot项目使用SchedulingConfigurer实现多个定时任务,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-01-01
  • JCrontab简单入门实例详解

    JCrontab简单入门实例详解

    这篇文章主要为大家详细介绍了JCrontab简单入门实例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-12-12

最新评论