咸糖记录编程的地方

Do what you love and the money will follow.

目录
CMS 内存碎片 解决以及简单的垃圾回收机制介绍
/  

CMS 内存碎片 解决以及简单的垃圾回收机制介绍

首先我提出几个问题:

  • Java 的内存/垃圾回收机制是什么?

  • 什么是内存碎片 如何解决?

Java 不选用引用计数是因为它很难解决对象之间相互循环引用的问题。

为何要选择 这些地方作为GC ROOT? 因为首先你需要确定的GC ROOT 一定是对象存活的对象,而上图这些位置的对象都能保证存活,或者是不被GC所波及,因为GC所主要处理的位置是堆。

对于Java 的内存回收机制我们主要分为3种:

  • 标记-清除算法

    • 不足:效率不高,容易产生内存碎片。
  • 复制算法

    • 效率高,复制成本大。

    • 不足:如果是1:1模型,成本太高。

    • 分配担保策略

  • 标记-整理算法

    • 因为老年代的对象生存率高,所以使用复制算法效率会很差,就提出了这个标记-整理算法。

我们可以发现每个算法都有他的优劣点,所以JVM 开发者们设计出了 一种名叫 ”分代收集“的方式进行垃圾回收。

新生代选用复制算法,因为剩下的存活对象少

老年代选用"标记—清理","标记—整理"的算法做


前置知识 什么是内存碎片?

内部碎片

分配内存到进程A,内存被进程占据了而不被利用,同时系统也无法利用这块内存,直到进程A被终结,释放内存。

外部碎片

还没被分配出去的内存太少了不足分配给下一个进程,又或者多个不连续的内存总空间长度能满足新申请的进程,但是由于地址是不连续的内存,无法分配给新进程。

Java 中的内存碎片可以理解为外部碎片,因为标记-清除算法只负责将标记的需要回收的内存给回收,对于一块内存,会留下很多小的空的位置,但是这些位置不足以去申请一个连续的对象。

对于内存碎片的解决,我们首先要明确,产生内存碎片的主要是老年代,所以我们主要聊一下这个CMS 如何解决内存碎片。

CMS 提供了 -XX:+UseCMSCompactAtFullCollection 用于在CMS收集器顶不住要进行FullGC时开启内存碎片的合并整理过程。虽然内存碎片没有了,但是停顿时间会变长很多很多,虚拟机设计者提供了 -XX:CMSFullGCsBeforeCompaction,在上一次CMS并发GC执行过后,到底还要再执行多少次full GC才会做压缩。默认是0,也就是在默认配置下每次CMS GC顶不住了而要转入full GC的时候都会做压缩。


标题:CMS 内存碎片 解决以及简单的垃圾回收机制介绍
作者:xiantang
地址:http://xiantang.info/articles/2019/08/04/1564910225657.html

评论