一、分代

左图是运行时数据区逻辑图,右图是分代逻辑图,右图中上边部分是JDK1.8之前的,下图是JDK1.8之后的;两张图中相同颜色代表相同的区域。

从图中我们可以得出,新生代和老年代是属于堆的;在JDK1.8之前,方法区也称为老年代,JDK1.8之后,取消了老年代,取而代之的是元空间Meta Space,也即是1.8后,方法区的实现方式有老年代变为了元空间。

设计元空间的目的,一是规避永久代溢出的问题;二是类似ArrarList,可以自动扩容。

1、为什么分代

因为对象的生命周期不一样,有的对象朝生夕死,一次minorGC的时候,大概98%的对象会被回收。但是有的对象生命周期比较长,如果堆内存不分代,所有对象存在相同的区域,那么垃圾回收的时候就会变的很复杂。分代后,垃圾回收就可以按区域的不同,采用不同的回收方式,比如新生代GC回收称为minor GC,老年代的GC回收称是GC,还有Full GC,同时回收新生代和老年代。

2、新生代为什么是8:1:1?

新生代采用的GC方式是复制回收算法,具体方式下边会讲到,这种算法第一次执行minorGC后,还存活的对象会复制到S0区,第二次执行minorGC,eden和S0中还存活的对象会被复制到S1区,如果接下里某次的minorGC后,存活的对象在S1区放不下了,就会存入老年代。

我们的理想的情况是不进入老年代。如果是9:1的话,第一次minorGC后存活的对象复制到S0区,下一次minorGC,存活的对象就会被放入老年代,但我们的理想情况是不进入老年代。所以如果是8:1:1的话,就可以多一份缓冲,占8份的Eden放不下了,触发minor gc,回收后存活的放入s0;eden再次分配,且只能在Eden去分配 ,Eden再次放不下时再次触发minor gc,这次会回收Eden和S0中的内从,存活的放入S1;如果某次回收后S1也放不下,再存入老年代。

以上均是大白话解释,又不准的地方望各位指正。接下来我们看看GC算法。

我们先看看哪些内存需要回收:

程序计数器、虚拟机栈、本地方法栈是每个线程私有的内存空间,随线程而生,随线程而亡。因此这3个须臾的内存分配和回收是确定的,无需考虑内存回收的问题。

但方法区和堆就不同了,一个接口的多个实现类需要的内存可能不一样,我们只有在程序运行期间才会知道创建哪些对象,这部分内存的分配和回收都是动态的,GC主要关注的是这部分内存。总而言之,GC主要进行回收的内存是JVM中的方法区和堆。

二、GC

1、对象创建

在语言层面上,创建对象通常仅仅是一个new关键字而已,而在虚拟机中,一个普通对象的创建是怎样的呢?

虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有,那必须先执行响应的类加载过程,在类加载检查通过后,接下来虚拟机将为新生对象分配内存。

2、对象分配

对象分配有两种方式:指针碰撞和空闲列表。

2.1、指针碰撞,适用于内存规整的情况,所有分配的内存都是规整的放到一边,空闲的另一边,中间有指针作为指示器,如果新来的对象,就把指针方空闲区挪动一部分

2.2、空间列表适用于内存不规整的情况,需要空间列表来记录内存使用情况

3、什么样的对象需要回收

什么样的对象需要回收,也就是Java的GC什么时候回收垃圾。有两种判断算法,来判断何时就可以回收了:引用计算法和可达性分析

3.1、引用计算法(废弃)

就是给对象添加一个引用计数器,每当有一个地方引用他时,计数器值就加1;当引用失效时,计数器值就减1;任何时刻计数器为0的对象就是可以被回收的。

但是这样方法存在一个问题,就是循环引用给的问题,如果a引用了b,b引用了a,a的计算为1,b的计算也为1,这样他两的计算为1,GC就一直无法回收。同时每次计数器的增加和减少都带来了很多额外的开销,所以在JDK1.1之后,这个算法已经不再使用了。

3.2、可达性分析(使用)

就是通过一系列的称为GC Roots的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到任何一个GC Roots都没有引用链相连时,就证明该对象可以被回收了。

哪些对象可称为GC Roots呢?

是否可以称为GC Roots的关键在于,如果一个线程在运行某个方法,那么这个方法中的变量就是存活状态,就是不应该被回收的,那么这个变量就可以作为GC Roots。

所以可以作为GC Roots的对象有:

  1. 虚拟机栈中本地变量表引用的对象
  2. 方法区中类静态变量引用的对象和常量引用的对象
  3. 本地方法栈中JNI引用的对象

4、java中引用类型有哪些

上边判断什么样的对象需要回收的两种方法,都涉及到引用,Java中对象的引用分为四种级别,这四种级别由高到低依次为:强引用、软引用、弱引用、虚引用。这四种引用均存在于堆中,一个对象属于内中引用,有他的最强的引用决定。

4.1、强引用

我们写代码天天在用的就是强引用、如果一个对象被人拥有强引用,那么垃圾回收器绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出OouOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足问题。

4.2、软引用 SoftReference

如果一个对象具有软引用,那么如果内存空间足够,垃圾回收器就不会回收它,如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收期没有回收它,该对象就可以被程序使用。

软引用可用来实现内存敏感的高速缓冲。在jvm报告内存不足之前会清除所有的软引用,这样一来gc就有可能手机软可及的对象,可能解决内存吃紧问题,避免内存溢出。什么时候被收集取决于gc的算法和gc运行时可用内存大小。

4.3、弱引用 WeakReference

如果一个对象只具有弱引用,那该类就是可有可无的对象,因为只要该对象被gc扫描到了随时都会把它干掉。弱引用和软引用给的区别就是:不管当前内存空间是否足够,只要gc扫描到随时会回收。

4.4、虚引用 PlantomReference

虚引用就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么他就和没有任何引用一样,在任何时候都可能被垃圾回收。虚引用主要用来跟踪对象被垃圾回收的活动。

5、回收方法

回收方法有三种:标记-清除算法、复制回收算法、标记-整理算法、还有分代收集算法

5.1、标记-清除算法

先标记要回收的对象,然后统一回收;适用于对象较多的垃圾回收;缺点是标记清除后产生大量不连续的内存碎片,给大对象分配内存时没有足够连续的内存空间,导致提前出发垃圾回收动作。

5.2、复制回收算法

将可用内存划分成相等大小两块,每次只使用其中一块,当这一块用完后将还存活的对象复制到另一块,然后将已使用过的内存一次清理。

适用于存活对象较少的垃圾回收;

优点是每次对整个半区进行内存回收,不用考虑内存碎片问题,只要移动堆顶指针,按顺序分配内存即可;实现简单,运行高效

缺点是将内存缩小了一半;

新生代采用的正是复制回收算法。新生代内存按照8:1:1分为Eden,From Survivor,To Survivor三个空间,每次使用Eden和From Survivor两个空间给对象分配内存,当内存不足垃圾回收时,将存活对象复制到To Survivor空间,然后清理Eden和From Survivor空间;这样相当于内存指浪费了10%;如果10%的To Survivor空间不够存放存活对象时需要老年代进行分配担保(将存活对象通过分配担保机制直接进入老年代)

5.3、标记-整理算法

先标记要回收的对象,将存活对象移至一端,最后清理端边界以外的内存;这样回收后不会产生内存碎片。

5.4、分代收集算法

根据对象存活周期将内存划分为新生代和老年代,然后根据每个年代的特点使用合适的回收算法;如:新生代存活对象少可以采用复制算法; 老年代存活对象多并且没有分配担保必须使用标记清理或标记整理回收算法

6、垃圾回收器

如果两个收集器之间存在连线,就说明他们可以搭配使用。

新生代收集器

6.1、Serial收集器,收集时必须暂停其他所有用户线程,直到收集结束。

6.2、parNew收集器,是Serial收集器的多线程版本

6.3、Parallel Scavenge收集器,主要关注吞吐量的控制,关注时间利用率

吞吐量 = 运行用户代码时间 / (运行用户代码时间 + 垃圾收集时间) ; 如果虚拟机总共运行100分钟,收集花费1分钟,则吞吐量为99%

老年代收集器

6.4、Serial Old收集器,是Serial收集器的老年代版本的单线程收集器

6.5、Parallel Old收集器,是Parallel Scavenge收集器的老年代版本的多线程收集器

6.6、CMS收集器(Concurrent Mark Sweep),CMS是一款并发收集,低停顿的收集器,关注目标是最短回收停顿时间

6.7、G1收集器,采用标记-整理算法,原理是G1将新生代和老年代分为大小相等的独立区域,进行全区域垃圾回收,新生代和老年代不再是物理隔离,都是部分独立区域的集合;通过计算每个区域垃圾堆积的价值(回收可得到的空间/回收所需要的时间),然后根据价值大小有优先级地进行垃圾回收,保证了回收的效率;

----------------------------------有不正确的望各位指正。-----------------------------------------------

【JVM】- 分代、GC算法相关推荐

  1. jvm 分代回收算法通俗理解

    jvm区域总体分两类,heap区和非heap区.heap区又分:Eden Space(伊甸园).Survivor Space(幸存者区).Tenured Gen(老年代-养老区). 非heap区又分: ...

  2. JVM内存管理------GC算法精解(五分钟教你终极算法---分代搜集算法)

    转载自   JVM内存管理------GC算法精解(五分钟教你终极算法---分代搜集算法) 引言 何为终极算法? 其实就是现在的JVM采用的算法,并非真正的终极.说不定若干年以后,还会有新的终极算法, ...

  3. 26 Java GC算法 垃圾收集器、标记 -清除算法、复制算法、标记-压缩算法、分代收集算法

    26.Java GC算法 垃圾收集器 1.1.1标记 -清除算法 1.1.2复制算法 1.1.3标记-压缩算法 1.1.4分代收集算法 26.Java GC算法 垃圾收集器 概述 垃圾收集 Garba ...

  4. JVM分代回收机制和垃圾回收算法

    JVM系列文章目录 初识JVM 深入理解JVM内存区域 玩转JVM对象和引用 JVM分代回收机制和垃圾回收算法 细谈JVM垃圾回收与部分底层实现 Class文件结构及深入字节码指令 玩转类加载和类加载 ...

  5. 欧尼酱讲JVM(22)——分代收集算法

    目录 分代收集算法 HotSpot中的分代收集 年轻代 老年代 没有一种最好的算法吗?没有,没有最好只有最适合.具体问题具体分析! 上一篇文章<欧尼酱讲JVM(21)--垃圾回收相关算法> ...

  6. (七)JVM成神路之GC分代篇:分代GC器、CMS收集器及YoungGC、FullGC日志剖析

    引言 在<GC基础篇>中曾谈到过分代以及分区回收的概念,但基础篇更多的是建立在GC的一些算法理论上进行高谈阔论,而本篇则重点会对于分代收集器的实现进行全面详解,其中会涵盖串行收集器.并行收 ...

  7. JVM学习-分代收集算法

    分代收集算法 1.分代回收算法概述 1.1.分代回收算法简介 1.2.回收流程 1.3.回收流程总结 2.相关VM参数 3.GC分析 1.分代回收算法概述 1.1.分代回收算法简介 我们在前面讲了三种 ...

  8. Jvm 系列(三):GC 算法 垃圾收集器

    这篇文件将给大家介绍GC都有哪几种算法,以及JVM都有那些垃圾回收器,它们的工作原理. 概述 垃圾收集 Garbage Collection 通常被称为"GC",它诞生于1960年 ...

  9. JAVA之JVM分代垃圾回收策略(一)

    一.为什么要分代 分代的垃圾回收策略,是基于这样一个事实:不同的对象的生命周期是不一样的.因此,不同生命周期的对象可以采取不同的收集方式,以便提高回收效率. 在Java程序运行的过程中,会产生大量的对 ...

  10. 【Android 内存优化】内存抖动 ( 垃圾回收算法总结 | 分代收集算法补充 | 内存抖动排查 | 内存抖动操作 | 集合选择 )

    文章目录 一. 垃圾回收算法总结 二. 分代收集算法补充 三. 查看 Java 虚拟机 四. 获取 Android 应用可使用最大内存 五. 内存抖动标志 六. 排查内存抖动 七. 常见的造成内存抖动 ...

最新文章

  1. js-ES6学习笔记-module(4)
  2. 解决: is not accessible from java.lang.Class android.app.AppComponentFactory
  3. BT[2]-BLE初体验:心率计
  4. 利用快排查询无序数组第k位大的数
  5. HTML <cite> 标签
  6. 组件化开发实战_一篇文章搞懂什么是前端“组件化”开发
  7. python 学习笔记一
  8. 管理活动目录域服务实训_2019级酒店管理专业前厅与客房服务校外课程实训总结篇...
  9. mysql 实施索引_MySQL 索引实现
  10. hbase集群 数据写入_HBase神器 | BDSHBase集群之间数据迁移同步的利器
  11. 如何使用U盘替换光驱引导部署WES7系统
  12. Steam的Hacknet的账户损坏问题
  13. 在QQ远程协助为什么键盘无法输入?一起来学习!
  14. 网友鸿蒙谷歌的Android,华为鸿蒙OS已经确认更名?新名字更加令人惊艳!网友:过目难忘...
  15. 天阳科技-宁波银行面试题【杭州多测师】【杭州多测师_王sir】
  16. sql面试题,查询出每班每科最高分的学生
  17. 解决h5 在微信放大字体中的问题
  18. 未来电竞旗舰:iQOO 8系列售价3799元起
  19. js获取当前时间的年月日时分秒以及时间的格式化
  20. HDU 5446 Unknown Treasure(Lucas定理+CRT)

热门文章

  1. pytorch yolov5 onnx推理
  2. notes java api_lotus-notes-使用Java API读取Lotus Notes文档
  3. 郭盛华:黑客使用社会工程学进行欺骗的3种方式
  4. Unity中如何给你的场景模型mesh减面——【一】
  5. Python爬虫从入门到精通:(43)JS逆向:完美世界RAS逆向_Python涛哥
  6. 【Filter过滤器案例】登录验证+敏感词过滤
  7. Linux在启动卡死
  8. 为什么EDA软件对芯片设计如此重要?
  9. 目前就常用计算机类型,CAD-CAM练习题
  10. 采集淘宝或天猫商品的店铺名称/商家旺旺/商品首图/商品标题