生存还是死亡

对象是否需要被垃圾收集器回收主要有两种方式:引用计数法可达性分析算法

引用计数法

给对象添加一个引用计数器,每当有一个地方引用他的时候,计数器的数值就+1,当引用失效时,计数器就-1;任何时候计数器的数值都为0的对象时不可能再被使用的。

客观的来说,引用计数法实现简单,判定效率高,但是无法解决对象的循环引用的问题。所以现在的虚拟机很少使用这种算法辣判断对象是否存活。

可达性分析算法

基本思路就是:通过一系列称为GC Roots的对象作为起始点,从这些起始点开始向下搜索,搜索所搜过的路径称为引用链Reference Chain,当一个对象到GC Roots没有任何引用链相连接时,则证明此对象时不可用的。如下图所示:4,5就被判定为需要回收的对象

GC Roots

在虚拟机中可作为GC Roots的对象包括以下几种:

  • 虚拟机栈中引用的对象
  • 方法区中类静态属性引用的对象
  • 方法区常量引用的对象
  • 本地方法栈引用的对象

    GC算法

    在被可达性分析算法判定为需要被回收的对象时,需要进行垃圾回收操作,垃圾回收算法有以下几种:

标记清除(mark-sweep)

最基础的收集算法,如同 它的名字一样,算法分为标记清除两个阶段:首先标记出需要被回收的对象,在标记完成后统一回收所有被标记的对象,它的标记过程其实就是上面所讲的可达性分析算法被标记为没有GC roots的引用链。过程如下:

不足
  • 效率问题,标记和清除两个过程的效率都不高
  • 空间问题,标记清除和产生大量不连续的内存碎片,内存碎片过多容易导致以后在程序运行的过程中需要分配大对象时,无法找到足够的连续内存而不得不提前触发一次垃圾收集动作。

    适用场景

    适用于老年代。因为老年代回收的几率小且不频繁能减少内存碎片

    复制 (coping)

    为了解决标记-清除得到效率问题,复制算法就出现了;它的原理是将可用内存容量划分为两个大小相等的内存块,每次只使用其中的一个,当这个的容量用完了。就将还存活的对象复制到另外一块上面去,然后再把已使用过的内存空间全部清理掉。这样使得每次都是对整个半区进行内存回收,内存分配就不用考考虑碎片等复杂情况


    研究表明,新生代中的对象98%都是朝生夕死的,所以按照并不需要1:1来划分空间。而是将内存分为一块较大的Eden空间和两个较小的Survivor空间,每次使用Eden和其中一款Survivor。一般比例是Eden : Survivor = 8:1

    不足
  • 空间利用率只有50%,但是经过适当的调整Eden和Survivor的比例能达到70%
  • 复制收集算法在对象存活率较高时就要进行较多的复制操作,效率将会变低

    适用场景

    使用了对象存活率较低的内存空间,如Eden区。

    标记整理

    是标记-清除算法的升级版本。标记过程任然与标记-清除算法一样,但是后续的处理步骤不是直接对可回收对象进行清理,而是让所有存活对象都向一端移动,然后直接清理掉端边界意外的内存、标记-整理算法示意图如下:

JAVA GC算法详解的更多相关文章

  1. Java GC机制详解

    垃圾收集 Garbage Collection 通常被称为“GC”,本文详细讲述Java垃圾回收机制. 导读: 1.什么是GC 2.GC常用算法 3.垃圾收集器 4.finalize()方法详解 5. ...

  2. Java GC 日志详解(转)

    Java GC日志可以通过 +PrintGCDetails开启 以ParallelGC为例 YoungGC日志解释如下(图片源地址:这里) : FullGC(图片源地址:这里): http://blo ...

  3. Java GC 日志详解

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt105 java GC日志可以通过 +PrintGCDetails开启 以Pa ...

  4. JVM内存管理--GC算法详解

    标记/清除算法 首先,我们回想一下上一章提到的根搜索算法,它可以解决我们应该回收哪些对象的问题,但是它显然还不能承担垃圾搜集的重任,因为我们在程序(程序也就是指我们运行在JVM上的JAVA程序)运行期 ...

  5. java gc日志详解

    从 Full GC 信息可知,新生代可用的内存大小约为 18M,则新生代实际分配得到的内存空间约为 20M(为什么是 20M? 请继续看下面...).老年代分得的内存大小约为 42M,堆的可用内存的大 ...

  6. 八大排序算法详解(动图演示 思路分析 实例代码java 复杂度分析 适用场景)

    一.分类 1.内部排序和外部排序 内部排序:待排序记录存放在计算机随机存储器中(说简单点,就是内存)进行的排序过程. 外部排序:待排序记录的数量很大,以致于内存不能一次容纳全部记录,所以在排序过程中需 ...

  7. JVM的GC理论详解

    GC的概念 GC:Garbage Collection 垃圾收集.这里所谓的垃圾指的是在系统运行过程当中所产生的一些无用的对象,这些对象占据着一定的内存空间,如果长期不被释放,可能导致OOM(堆溢出) ...

  8. 最新java数组的详解

    java中HashMap详解 http://alex09.iteye.com/blog/539545 总结: 1.就像引用类型的数组一样,当我们把 Java 对象放入数组之时,并不是真正的把 Java ...

  9. 转:Java HashMap实现详解

    Java HashMap实现详解 转:http://beyond99.blog.51cto.com/1469451/429789 1.    HashMap概述:    HashMap是基于哈希表的M ...

随机推荐

  1. redis维护节点常用操作

    维护节点 添加主节点 hash槽重新分配 添加从节点 删除结点 1 添加主节点 集群创建成功后可以向集群中添加节点,下面是添加一个master主节点 添加7007结点作为新节点 执行命令:./redi ...

  2. LeetCode No.100,101,102

    No.100 IsSameTree 相同的树 题目 给定两个二叉树,编写一个函数来检验它们是否相同. 如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的. 示例 输入: 1 1 / \ ...

  3. day35-子进程的开启

    #1.异步非阻塞: import os from multiprocessing import Process def func(): print('子进程:',os.getpid()) if __n ...

  4. 常见字体图标库——font-awesome

    1.简介 FontAwesome一种带有网页功能的象形文字语言,并收集在一个集合里.字库中有675个图标,只支持英文搜索,中文地址:http://www.fontawesome.com.cn/ 2.使 ...

  5. zabbix 扩展脚本

    #!/usr/bin/env python #encoding:utf8 # desc: self-inspection # args: # reboot : reboot AP # check : ...

  6. verilog乘法器的设计

    在verilog编程中,常数与寄存器变量的乘法综合出来的电路不同于寄存器变量乘以寄存器变量的综合电路.知乎里的解释非常好https://www.zhihu.com/question/45554104, ...

  7. 瑞星发布Linux系统安全报告:Linux病毒或将大面积爆发

    近半年来,由于中央推荐使用国产Linux操作系统,国产Linux操作系统开始受到政府机关及大型企事业机关单位的高度重视.很多人都认为,以Linux系统为基础的国产操作系统最符合国家.政府和企业信息安全 ...

  8. 4k高分屏下,chm帮助文档,api文档打开后字体过小的解决

    如图所示: 4k分辨率下,chm文件的正文部分的字体过小,这是这些网页可能使用了CSS维持字体dpi, 在普通分辨率下,可以显示正常,但在高分屏下就会显示得过小,这时我们就需要调整显示网页 的显示效果 ...

  9. Linux上部署Tomcat+Nginx负载均衡

    前提:配置好了JDK. 我这里是vm上的linux虚拟机,可能不适用于所有情况. 一.Linux上配置Tomcat 1.下载地址:https://tomcat.apache.org/download- ...

  10. caffe之那些依赖的库

    1. Boost库 Boost是一个可移植的,提供源代码的C++库,作为标准库的后备,是C++标准化进程的开发引擎之一.Boost强调对跨平台的支持,编译与平台无关.Caffe采用C++为主要开发语言 ...