垃圾回收

标签(空格分隔): Java


那些对象需要回收

JVM内存结构主要包括: 方法区, 堆区, 程序计数器, 本地方法区, 虚拟机栈. 其中的程序计数器, 本地方法区, 虚拟机栈这三个区域是的生命周期随线程生灭, 所以不需要过多考虑这方面的GC问题.


引用

在JDK1.2之后, Java对引用的概念进行了补充, 总体分为四类: 强引用, 软引用, 弱引用, 虚引用. 这四种引用强度逐渐减弱.

  • 强引用 : 指在代码中普遍存在的, 类似 Object object = new Object();这类的引用, 只有强引用还存在, GC就永远不会收集被引用的对象.
  • 软引用 : 指一些还有用但并且非必须的对象. 直到内存空间不够时(抛出OutofMemoryError之前), 才会被垃圾回收. 采用SoftReference类来实现软引用.
  • 弱引用 : 用来描述非必须对象. 当垃圾收集器工作时就会回收掉此类对象. 采用WeakReference类来实现弱引用.
  • 虚引用 : 一个对象是否有虚引用的存在, 完全不会对其生存空间构成影响, 唯一目的就是能在这个对象被回收的时候收到一个系统通知, 采用PhantomRenference类实现.

如何判断对象已死


1. 引用计数法

为每一个对象的的数据结构添加一个引用计数器, 用于统计指向该对象的引用的数量, 每当多一个引用的时候, 其引用计数器就加一, 当引用不再指向该地址之后计数器减一. 一旦计数器的值为0,则表示没有引用指向该对象, 则对象已经死亡 ( <<寻梦环游记>> 说的: 人真正的死亡是所有活着的人的都忘了你的时候).

优点:

  1. 效率很高.

缺点:

  1. 每个对象都需要在其原有的数据结构之上添加一个引用计数器的属性.
  2. 循环引用的话就永远不会被标记为死亡.( 对象A引用了对象B, 对象B也引用了对象A )

2. 可达性分析.

目前JVM的主流垃圾回收器采取的可达性分析算法, 这个算法的实质在于将一系列GC Roots作为初始的存活对象的集合(Live Set), 然后从该集合出发, 探索所有能过被集合直接或间接引用的对象, 并且将其加入集合之中, 这个过程就是标记过程. 最终, 未被探索到的对象便是死亡, 是可以回收的.

什么是GC Roots, 其实就是由堆外指向堆内的引用.

  1. JMM虚拟机栈 栈帧中的局部变量.
  2. JMM方法区中的静态属性, 常量引用对象.
  3. JMM本地方法区中的, JNI中引用的对象.

可达性分析, 可以解决循环引用问题, 但是自身也存在一些问题, 比如说在多线程的情况下, 其他线程可能会更新已经访问过的对象的引用, 造成漏删. 解决方案是 进行两次可达性分析, 如果两次某对象都被标记则进行删除.


如何删除无效对象.


1. 标记清除算法

由名可得: 标记->清除. 得到需要清除的对象之后就直接进行清除.

优点: 速度快

缺点: 多次GC之后, 造成大量的碎片空间. 对于需要连续存储的较大对象无法存储, OutofMemoryError


2. 标记整理算法

由名可得: 标记->清除->移动整理. 对标记清除算法的一次改进, 但是因为移动操作, 所以时间成本较高.

优点: 没有内存碎片.

缺点: 时间成本较高.


3. 复制算法.

将可用的内存按容量分为大小两块, 每次只是用其中一块, 当这一块的内存用完了, 就将还存活着的对象复制到另一块内存上, 然后再把已使用的内存空间清理掉.

每次当内存分配的时候空间不够的时候, 都进行复制算法进行内存整理.

优点: 实现简单, 效率高. 解决了标记清除算法导致的内存碎片问题.

缺点: 代价太大, 将内存缩小了一半. 效率随对象的存活率升高而降低.

3.1 HotSpot虚拟机的改良算法

  1. 弱代理论
  • 分代垃圾收集基于弱代理论, 具体描述如下:
  • 大多分配了内存的对象并不会存活太长时间, 在处于年轻时代的时候就会死掉.
  • 很少有对象会从老年代变为年轻代.
  • 其中IBM研究表明: 新生代中的98%的对象都是 朝生夕死 ; 所以不需要按照1:1比例来划分内存.
  1. Hotspot虚拟机新生代内存布局以及算法.
  • 新生代内存分配一块较大的Eden和两块较小的Survivor空间.
  • 每次使用Eden和其中Survivor空间.
  • 回收时将EdenSurvivor空间中存活的对象一次性的复制到另一块Survivor空间上.
  • 最后清理掉Eden和使用过的Survivor空间.

Hotspot默认EdenSurvivor的大小比例是8:1 .

分配担保:

如果另一块Survivor空间没有足够的内存来存放上一次新生代收集下来的存活对象, 那么这些对象则直接通过担保机制进入老年代.


4. 分代收集算法

当前商业虚拟机的垃圾收集器都是采用分代收集算法, 根据对象存活周期的不同将内存划分为几块. 一般把Java堆分为新生代, 老年代. JVM根据各个年代的特点采用不同的手机算法.

  • 新生代中, 每次进行垃圾回收都会发现大量对象死去, 只有少量存活, 因此比较适合复制算法. 只需要付出少量的存活对象的复制成本就可以完成收集.
  • 老年代中, 因为对象的存活率比较高, 没有额外的空间进行分配担保, 所以比较适合标记-清理, 标记-整理算法来进行回收.

Java堆是JVM所管理的内存的最大的一块, 也是GC主要的工作区. 其主要分为两个区 年轻代老年代, 其中年轻代又分为EdenSurvivor区, 其中Survivor区又分为FROMTo两个区. 可能这个时候大家又会有疑问, 为什么需要Survivor区, 为什么Survivor还要分为两个区?

Eden区 : IBM表示有98%的对象是朝生夕死, 所以针对这一现状, 大多数情况下, 对象会在新生代Eden区中进行分配, 当Eden区没有足够的空间进行分配的时候, 虚拟机会发起一次GC. 通过这次GC之后,Eden会被清空, Eden区中绝大部分的对象会被回收, 而那些无需回收的存货对象, 将会进到SurvivorFROM区(若FROM不够, 则直接进入Old区).

Survivor区: 相当于是Eden区和Old区的一个缓冲, 类似于我们交通中的黄灯. Survivor又分为两个区, 一个为From区, 一个是To区. 每次执行Minor GC 会将Eden区和FROM存活的对象放到SurvivorTo区(如果To则直接进入Old区).

不是新生代到老年代么, 直接中EdenOld不好了么,为什么要这么复杂. 如果没有Survivor区, Eden区每一次GC, 存活的对象就会被送到老年代, 老年代很快就会被填满, 而虽然有很多对象虽然一次没有被消灭掉,但是也存活不了太多次, 这个时候将其移入Old区会很快的将其填满.

所以Survivor的存在意义就是减少被送到老年代的对象, 进而减少GC的发生. Survivor的筛选保证, 只有经历16此的GC还能再新生代存活的对象,才会被送到老年代.

Old区占据着2/3的堆内存空间,只有在Marjor GC的时候才会进行清理, 每次GC都会出发stop-the-world. 内存越大, SWT的时间也越长, 所以内存也不仅仅是越大越好, 由于复制算法的对象存活率较高的老年代会进行很多次的复制操作, 效率很低, 所以老年代这里采用的是 标记整理算法.


除了上述所说, 在内存担保机制的情况下, 无法安置的对象也会直接进入老年代, 以下几种情况也会进入老年代.

  • 大对象: 指需要大量连续内存空间的对象, 这部分对象不论是不是"朝生夕死", 都会直接进入到老年代, 这样做主要是为了避免在Eden区以及两个Survivor区之间发生大量的内存复制, 当你的系统有非常多的"朝生夕死"的大对象的时候, 就值得注意了.
  • 长期存活对象: 虚拟机给每个对象定义了一个对象年龄(Age)计数器. 正常情况下的对象会不断的在SurvivorFROMTo之间进行移动, 对象在每经历一次Minor GC, 年龄就会自增1, 当年龄增加到15岁的时候, 就会被移入老年代. 这里的15是可以进行自定义的.
  • 动态对象年龄: 虚拟机并不重视对象的年龄必须大于15岁, 才会放入老年区, 如果Survivor空间中相同年龄所有对象的总和大于Survivor空间的一般, 年龄大于等于该年龄的对象就可以直接进入老年区.

Java-GC-标记清除算法的更多相关文章

  1. Java GC 标记/清除算法

    1) 标记/清除算法是怎么来的? 我们在程序运行期间如果想进行垃圾回收,就必须让GC线程与程序当中的线程互相配合,才能在不影响程序运行的前提下,顺利的将垃圾进行回收. 为了达到这个目的,标记/清除算法 ...

  2. 《垃圾回收的算法与实现》——GC标记-清除算法

    基本算法 标记-清除算法由 ==标记阶段== 和 ==清除阶段== 构成. 标记即将所有活动的对象打上标记. 清除即将那些没有标记的对象进行回收. 标记与清除 遍历GC root引用,递归标记(设置对 ...

  3. 1. GC标记-清除算法(Mark Sweep GC)

    世界上第一个GC算法,由 JohnMcCarthy 在1960年发布. 标记-清除算法由标记阶段和清除阶段构成. 标记阶段就是把所有的活动对象都做上标记的阶段. 标记阶段就是"遍历对象并标记 ...

  4. JVM内存管理------GC算法精解(五分钟让你彻底明白标记/清除算法)

    相信不少猿友看到标题就认为LZ是标题党了,不过既然您已经被LZ忽悠进来了,那就好好的享受一顿算法大餐吧.不过LZ丑话说前面哦,这篇文章应该能让各位彻底理解标记/清除算法,不过倘若各位猿友不能在五分钟内 ...

  5. GC算法精解(五分钟让你彻底明白标记/清除算法)

    GC算法精解(五分钟让你彻底明白标记/清除算法) 相信不少猿友看到标题就认为LZ是标题党了,不过既然您已经被LZ忽悠进来了,那就好好的享受一顿算法大餐吧.不过LZ丑话说前面哦,这篇文章应该能让各位彻底 ...

  6. JVM内存管理之GC算法精解(五分钟让你彻底明白标记/清除算法)

    相信不少猿友看到标题就认为LZ是标题党了,不过既然您已经被LZ忽悠进来了,那就好好的享受一顿算法大餐吧.不过LZ丑话说前面哦,这篇文章应该能让各位彻底理解标记/清除算法,不过倘若各位猿友不能在五分钟内 ...

  7. (转)jvm具体gc算法介绍标记整理--标记清除算法

    转自:https://www.cnblogs.com/ityouknow/p/5614961.html GC算法 垃圾收集器 概述 垃圾收集 Garbage Collection 通常被称为“GC”, ...

  8. JVM之GC算法、垃圾收集算法——标记-清除算法、复制算法、标记-整理算法、分代收集算法

    标记-清除算法 此垃圾收集算法分为“标记”和“清除”两个阶段: 首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记对象,它的标记过程前面已经说过——如何判断对象是否存活/死去 死去的对象就会 ...

  9. Java GC 垃圾回收算法 内存分配

    垃圾回收(Garbage Collection, GC)是Java不同于c与c++的重要特性之一. 他帮助Java自动清空堆中不再使用的对象. 由于不需要手动释放内存,程序员在编程中也可以减少犯错的机 ...

  10. JVM-GC算法(一)-标记清除算法

    首先,我们得知道根搜索算法,它可以解决我们应该回收哪些对象的问题,但是它显然还不能承担垃圾搜集的重任,因为我们在程序(程序也就是指我们运行在JVM上的JAVA程序)运行期间如果想进行垃圾回收,就必须让 ...

随机推荐

  1. Java多线程系列 基础篇02 线程的创建和运行

    1.线程创建的方式常用有两种 1. 继承 Thread 类创建线程 2. 实现 Runnable 接口创建线程 2.Thread 和 Runnable的区别 Thread和Runnable的相同点:都 ...

  2. CSS3定时提示动画特效

    在线演示 本地下载

  3. Java接口 详解(二)

    上一篇Java接口 详解(一)讲到了接口的基本概念.接口的使用和接口的实际应用(标准定义).我们接着来讲. 一.接口的应用—工厂设计模式(Factory) 我们先看一个范例: package com. ...

  4. ffmpeg拼接mp4视频

    首先需要把mp4格式的文件转成ts格式.拼接好之后,再将ts封装格式转换回mp4. ffmpeg -i 1.mp4 -vcodec copy -acodec copy -vbsf h264_mp4to ...

  5. storm--chuanzhiboke

    Storm里面有7种类型的stream grouping 1. Shuffle Grouping: 随机分组, 随机派发stream里面的tuple,保证每个bolt接收到的tuple数目大致相同. ...

  6. 【前端】jQuery DataTables 使用手册(精简版)

    转载请注明出处:http://www.cnblogs.com/shamoyuu/p/5182940.html 前排提醒,这个插件能不用就不用,那么多好的插件等着你,为什么要用它呢?就算用easyui的 ...

  7. ogg概叙、架构、进程

    一. OGG 概述 OGG 全称Oracle Golden Gate. 历史: Golden Gate公司于1995年成立于美国加州旧金山,它的名称源自旧金山闻名于世的金门大桥.两位创始人Eric F ...

  8. CentOS7的网络配置

    1.DNS配置 新安装的虚拟机,ping 内网IP可以,但是ping 外网域名却失败,告知“Name or service not known”. 原来是因为需要在/etc/sysconfig/net ...

  9. struts2的使用知识点

    最开始学习java的时候学习过struts,但是对配置和struts的理解深度不够,现在工作虽然再用,但是自己搭建环境和使用心得始终很零散,所以现在决定重新理一遍,有条理的学习一下struts. 至于 ...

  10. AI-Info-Micron-Insight:通往完全自主之路

    ylbtech-AI-Info-Micron-Insight:通往完全自主之路 1.返回顶部 1. 通往完全自主之路 自动驾驶汽车正在从未来梦想演变为当代现实,随着技术成熟,个人和公共交通将永远转变. ...