您的位置 首页 java

Java中的垃圾回收是个啥,白话JVM垃圾回收

Java 可以自动的进行垃圾回收,不需要开发人员手工处理,这是Java的优势之一。那么到底啥是垃圾回收,她又是如何进行的呢?

其实很简单,Java的运行是基于JVM虚拟机的,JVM中垃圾回收主要分两步:

  1. 查找内存中不再使用的对象
  2. 释放废弃对象占用的内存

一、查找内存中不再使用的对象

1、引用 计数法

引用计数法就是如果一个对象没有被任何引用指向,则可视之为垃圾。这种方法的缺点就是不能检测到环的存在。

2、根搜索算法

根搜索算法的基本思路就是通过一系列名为”GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。

二、释放废弃对象占用的内存

找到垃圾对象了,接下来就是清理。常见的方式有复制或者直接清理,但是直接清理会存在内存碎片,于是就会产生了清理再压缩的方式。

1、标记-复制

它将可用内存容量划分为大小相等的两块,每次只使用其中的一块。当这一块用完之后,就将还存活的对象复制到另外一块上面,然后在把已使用过的内存空间一次理掉。它的优点是实现简单,效率高,不会存在内存碎片。缺点就是需要2倍的内存来管理。

2、标记-清理

标记清除 算法 分为“标记”和“清除”两个阶段:首先标记出需要回收的对象,标记完成之后统一清除对象。它的优点是效率高,缺点是容易产生内存碎片。

3、标记-整理

标记操作和“标记-清理”算法一致,后续操作不只是直接清理对象,而是在清理无用对象完成后让所有 存活的对象都向一端移动,并更新引用其对象的指针。因为要移动对象,所以它的效率要比“标记-清理”效率低,但是不会产生内存碎片。

另外,还有基于分代的假设。由于对象的存活时间有长有短,所以对于存活时间长的对象,减少被gc的次数可以避免不必要的开销。这样我们就把内存分成新生代和老年代,新生代存放刚创建的和存活时间比较短的对象,老年代存放存活时间比较长的对象。这样每次仅仅清理年轻代,老年代仅在必要时时再做清理可以极大的提高GC效率,节省GC时间。

三、垃圾收集器的历史

1、Serial(串行)收集器

在jdk1.3.1之前,java虚拟机仅仅能使用Serial收集器。 Serial收集器是一个单 线程 的收集器,但它的“单线程”的意义并不仅仅是说明它只会使用一个CPU或一条收集线程去完成垃圾收集工作,更重要的是在它进行垃圾收集时,必须暂停其他所有的工作线程,直到它收集结束。

PS:开启Serial收集器的方式

-XX:+UseSerialGC

2、 Parallel (并行)收集器

Parallel收集器也称吞吐量收集器,相比Serial收集器,Parallel最主要的优势在于使用 多线程 去完成垃圾清理工作,这样可以充分利用多核的特性,大幅降低gc时间。

PS: 开启Parallel收集器的方式

-XX:+UseParallelGC -XX:+UseParallelOldGC

3、CMS(并发)收集器

CMS收集器在Minor GC时会暂停所有的应用线程,并以多线程的方式进行垃圾回收。在Full GC时不再暂停应用线程,而是使用若干个后台线程定期的对老年代空间进行扫描,及时回收其中不再使用的对象。

PS: 开启CMS收集器的方式

-XX:+UseParNewGC -XX:+UseConcMarkSweepGC

4、G1(并发)收集器

G1收集器(或者垃圾优先收集器)的设计初衷是为了尽量缩短处理超大堆(大于4GB)时产生的停顿。相对于CMS的优势而言是内存碎片的产生率大大降低。

PS:开启G1收集器的方式

-XX:+UseG1GC

其中G1收集器是最新型的垃圾收集器,颠覆了之前的方式,大家感兴趣可以去了解下。

文章来源:智云一二三科技

文章标题:Java中的垃圾回收是个啥,白话JVM垃圾回收

文章地址:https://www.zhihuclub.com/181003.shtml

关于作者: 智云科技

热门文章

网站地图