当前位置:首页 > 后端开发 > Java中的垃圾回收(GC)

Java中的垃圾回收(GC)

7个月前 (05-24)44

垃圾回收,英文名Garbage Collection(GC).

Java进程在启动后,会创建垃圾回收线程,来对内存中无用的对象进行回收.

目录

1. 那么问题来了,什么是垃圾?

2. 什么是垃圾回收?

3. 什么时候回收垃圾?

4. 判断是否为垃圾的算法

4.1 引用计数法

4.2 可达性分析算法

5. 回收的区域

5.1 方法区的gc

5.2 堆的gc

6. 垃圾回收算法

6.1 标记清除算法(老年代的回收算法)

6.2 复制算法(新生代的回收算法)

6.3 标记整理算法(老年代的回收算法)

6.4 分代收集算法

7. GC回收策略


1. 那么问题来了,什么是垃圾?

       Java中的垃圾回收(GC) _ Java侠

        Java进程运行后,如果某个类型(方法区中的类信息,堆中的类对象),常量(常量池),对象(堆),如果不可用,称为垃圾.

2. 什么是垃圾回收?

        Java进程启动后,gc垃圾回收守护线程会回收以上的垃圾对象.

3. 什么时候回收垃圾?

        创建对象时,需要在对应的内存区域分配内存空间,如果该区域不足,就触发该区域的gc.(侠客莫急,对应能回收的内存区域都有哪些,稍后介绍)

System.gc();  //只是建议jvm进行垃圾回收,不一定执行.

4. 判断是否为垃圾的算法

Java中的垃圾回收(GC) _ Java侠    

4.1 引用计数法

        给对象增加一个引用计数器,每当有一个地方引用它时,计数器就+1;当引用失效时,计数器就-1;任何时刻计数器为0的对象就是不能再被使用的,即对象已"死"。

        主流的jvm中,没有使用这种算法,因为无法解决循环引用的问题,如下图所示.

       Java中的垃圾回收(GC) _ Java侠

4.2 可达性分析算法

        此算法的核心思想为 : 通过一系列称为"GC Roots"的对象作为起始点,从这些节点开始向下搜索,搜索走过的路径称之为"引用链",当一个对象到GC Roots没有任何的引用链相连时(从GC Roots到这个对象不可达)时,证明此对象是不可用的.

        其中,GC Roots指的是: 当前时间点,线程运行某个方法,在方法栈帧中持有的引用对象.

        以下图为例:

       Java中的垃圾回收(GC) _ Java侠

 

        对象Object5-Object7之间虽然彼此还有关联,但是它们到GC Roots是不可达的,因此他们会被判定为可回收对象。

了解四种引用类型:

  • 强引用 : 普通的new对象,都是强引用,只要是可达的,任何情况下都不能回收.
  • 软引用 : 即使是可达的,如果要发生该区域的内存溢出(OOM),就会回收.
  • 弱引用 : 即使是可大的,如果该区域发生gc,就会回收.
  • 虚引用 : 任何情况下,都无法通过虚引用获取到对象.目的只是在该对象被回收时,通知jvm.

5. 回收的区域

不用回收的区域: 程序计数器;虚拟机栈(方法执行就是入栈,方法返回就是出栈,会自动清除栈帧内存,所以没有gc);回收的区域如下:

5.1 方法区的gc

        频率非常低的回收区域,由于回收的条件非常苛刻,所以效率也低,在jdk1.7叫方法区,jdk1.8叫元空间.

        方法区是设计层面的叫法,在具体实现,gc垃圾回收中,称为永久代.

5.2 堆的gc

        频率非常高的回收区域.方法中new对象,方法返回,栈帧就被清除了,也就意味着堆中new出来的对象没有任何引用指向它,就可以回收.

        堆在gc时,进一步被划分为以下的内存:

  Java中的垃圾回收(GC) _ Java侠

        (1) 年轻代的gc: 又称为Yong GC,Minor GC (次要的gc,对用户线程的影响来说,是次要) ;回收特点: 非常频繁,回收效率也非常高.

        (2) 老年代的gc: 又称为Old GC,major GC(主要的gc,是说对用户线程的影响是主要的,较大); 回收特点: 一般回收速度比Minor GC慢10倍以上.

        (3) 补充Full GC: 不同的场景下,可能指老年代gc,也可能是全堆gc,也可能是用户线程暂停的gc.

        eden伊甸区,西方文化中的亚当和夏娃在伊甸园偷吃了禁果,于是创造了人类.

6. 垃圾回收算法

JVM是使用垃圾回收线程来执行垃圾回收工作.

基于垃圾回收器执行垃圾回收工作,回收不可达对象.每一种垃圾回收器使用的回收算法可能不同,还可能有多种,依据垃圾回收算法执行垃圾回收工作.

6.1 标记清除算法(老年代的回收算法)

(1) 分为两个阶段

  • 标记: 标记不可达对象
  • 清除: 清理垃圾 

(2) 有两个缺陷

  • 标记和清除两个阶段效率都不高. 类似本地删文件,遍历某个文件夹,遍历10万个文件,标记1000个垃圾文件,再遍历1000个垃圾文件并删除.
  • 回收后存在内存碎片. 意味着在该区域创建大对象时,需要分配一块连续的空间,可能就不够.

6.2 复制算法(新生代的回收算法)

        将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这块内存需要进行垃圾回收时,会将此区域还存活着的对象复制到另一块上面,然后再把已经使用过的内存区域一次清理掉。

  Java中的垃圾回收(GC) _ Java侠

(1) 优点:

  • 效率高,对象朝生夕死,存活的对象不多,复制也很快,清理也很快.
  • 没有内存碎片的问题.

(2) 缺陷:

  • 空间利用率不高,只有50%.

6.3 标记整理算法(老年代的回收算法)

        复制收集算法在对象存活率较高时会进行比较多的复制操作,效率会变低。因此在老年代一般不能使用复制算法.

    Java中的垃圾回收(GC) _ Java侠

优点:

  • 存活对象较多的时候,移动效率也比较高.
  • 没有内存碎片问题.

6.4 分代收集算法

        当前JVM垃圾收集都采用的是"分代收集(Generational Collection)"算法,这个算法并没有新思想,只是根据对象存活周期的不同将内存划分为几块。

具体就是以上划分GC堆为:

(1) 新生代

  • Eden区
  • From Survivor(S0)
  • To Survivor(S1)

(2) 老年代

Java中的垃圾回收(GC) _ Java侠

  • 当次gc时,使用的空间为Eden+S0,gc完成后,S1还保留存活对象,程序继续执行,创建的对象存放在Eden区,如果创建对象时,Eden区空间不足,又会触发新生代的gc:重复以上步骤.

7. GC回收策略

(1) 对象优先分配在Eden区。

(2) 长期存活的对象进入老年代。新生代Minor GC后,存活在S区空间的对象,年龄+1,超过年龄阈值(默认15),就晋升到老年代。

(3) 大对象直接进入老年代,有设置JVM大对象的参数,超过大对象的阈值,直接进入老年代。目的:新生代空间相对老年代小很多,新生代使用复制算法,如果创建的大对象保存在新生代,复制起来效率低。

(4) 空间分配担保机制。

(5) 动态对象年龄判断,新生代gc时,存活对象中,某个年龄的对象总和大于S区空间/2,把大于等于该年龄的对象,存放在老年代。

 

 

作者:一颗苹果.
来源链接:https://blog.csdn.net/weixin_43939602/article/details/117948764

标签: 垃圾回收

“Java中的垃圾回收(GC)” 的相关文章

题5 正确的Java垃圾回收说法

考查对垃圾回收机制的理解 问:     关于Java垃圾回收,正确的是?     a.对于适用于垃圾回收的对...

【JVM】-- Java垃圾回收机制

【JVM】-- Java垃圾回收机制

目录 1.如何判断对象可以被回收 1.引用计数法 2.可达性分析算法 2.四种引用...

Java  垃圾回收机制 (GC) 一

Java 垃圾回收机制 (GC) 一

Java  垃圾回收机制 (GC) stop-the-world 会在任何一种GC算法中发生 ,Stop-the-world意味着 JVM 因为要执行GC而停止...

Java中垃圾回收(gc)问题

以下哪项陈述是正确的? A. 垃圾回收线程的优先级很高,以保证不再 使用的内存将被及时回收 B. 垃圾收集允许程序开发者明确指定释放 哪一个对象...

Java虚拟机调优(三)-基本垃圾回收算法

Java虚拟机调优(三)-基本垃圾回收算法

背景: java虚拟机的东西,一直想分享下,弄了半天,太过理论了,也写不出太多特别的东西,看已经有朋友分享的很好了,还整理成了一个系统,就转载...

Java-垃圾回收机制(GC策略)

Java-垃圾回收机制(GC策略)

核心:1,哪些是垃圾?【怎么确定这个是垃圾】;2,如何回收垃圾?【怎么更好收垃圾】。 Java语言相对于C++等语言有一个自动垃圾回收机制,...

Java面试题之Java虚拟机垃圾回收

Java面试题之Java虚拟机垃圾回收

  JVM的垃圾回收机制,在内存充足的情况下,除非你显式的调用System.gc(),否则不会进行垃圾回收;在内存充足的情况下垃圾回收会自动运行。 一、引用计数算法 1.定义...

java垃圾回收机制介绍

java垃圾回收机制介绍

一、垃圾回收机制 java中引入了一种独特的内存回收机制解决了过去在c++中令人头疼的内存管理问题,使得java程序员在编写程序的时候不必考虑...

java中垃圾收集的方法

java垃圾回收的方法是什么 说到垃圾回收(Garbage Collection,GC),很多人就会自然而然地把它和Java联系起来。在Java中,程序员不...

java两种核心机制之一--java垃圾回收机制

 一、谁在做Garbage Collection?    一种流行的说法:在C++里,是系统在做垃圾回收;而在Java里,是Java自身在做。在C++里...