JVM 垃圾回收机制和常见算法

时间:2024-01-01 11:09:57

垃圾回收机制:释放那些不再持有引用的对象的内存。

如何判断对象是否需要回收?

  1. 引用计数:对象,内存,磁盘空间等被引用次数保存起来,次数为0时将其进行释放。
  2. 对象引用遍历:对象应用遍历从一组对象开始,沿着对象图的每条链接,递归课到达对象,如果不能从根对象到达,则将它进行回收。

垃圾回收方法?

  1. 标记清除法:遍历对象图并记录可达对象,以便删除不可达对象,一般使用单线程工作并可能产生内存碎片,标记回收会分为“标记”、“清除”两阶段,先标记需要回收的对象,标记后统一进行清除。标记清除过程效率不高;

     JVM 垃圾回收机制和常见算法

  2. 标记整理法:遍历对象图并记录可达对象,以便删除不可达对象,一般使用单线程工作并可能产生内存碎片,并将存活对象压缩到内存的一端,这样内存碎片可以合成一整块可用内存区域,提高内存利用率,缺点进行对象移动,成本较高,好处是不会产生内存碎片。

  JVM 垃圾回收机制和常见算法

  3. 复制回收法:复制回收将可用内存划分为大小相等的两块,每次只是用其中一块,当这块使用完的时候,就将还存活的对象复制到另一块内存中去,然后在把已经使用过的内存空间一次性处理掉,这样使得每次都是对其中的一块进行内存回收,不会产生碎片等情况,只要移动对指针,按照顺序分配内存即可,实现简单,运行高效,缺点,内存占用多一半。

  JVM 垃圾回收机制和常见算法

  4. 分代回收法:根据对象的存活周期的不同将内存划分为几块,一般将java堆分为新生代和老年代,这样就可以根据各个年代的特点采用适当的收集算法:

  新生代:垃圾回收的时候发现大批对象死去,只有少量存活,那就选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。

  老年代:对象存活率高,没有额外空间对他进行分配担保,就必须使用标记清理算法进行回收。

垃圾回收器:

serial收集器:android 2.3之前采用这个收集器进行垃圾回收,会停止所有的UI操作。单线程收集器,只会使用一个CPU或一条线程去完成工作,进行垃圾回收的时候,暂停其他工作线程,直到工作完毕。对于限定单个CPU的环境,serial收集器没有线程交互,自然高效。

parNew收集器:serial收集器的多线程版本,运行在server模式下首选的收集器,能够和CMS收集器配合工作,CMS收集器是个优秀的并发垃圾收集器,parNew能与其搭配让parNew收集器更加完美。

parallel Scavenge收集器:新生代收集器,利用复制算法进行回收,并发多线程收集器,可控制吞吐量(运行用户代码时间/(运行用户代码时间+垃圾收集时间))的收集器。可以设置最大垃圾停留时间和吞吐量大小,打开垃圾收集将根据当前系统运行状态自动调节,这种方式成为GC自适应调节策略。手工优化存在困难的时候可直接交给虚拟机去完成。

G1收集器:结合空间整合,不会产生大量碎片,降低GC频率。可明确指定停顿时间,划分优先级操作,保证效率。

CMS收集器:获取最短回收停顿时间为目标的收集器。应用于互联网B/S架构的服务器上,重视响应时间。采用标记-清除算法,效率上占用CPU资源,使得应用程序变慢,无法处理浮动垃圾;算法是会产生大量碎片,无法为大对象分配内存的时候出发full gc,cms默认提供参数默认开启full gc。