前言

不同于C++程序员必须自己完成内存的分配、使用和释放,JAVA语言提供了垃圾回收机制(GC,Garbage Collection),所以JAVA程序员仅需要负责分配和使用内存即可,而释放内存则由GC负责。这样程序员就从讨厌的内存管理的工作中脱身了。本文主要给大家介绍一下JVM如何查找需要被回收的对象实例与垃圾收集算法。

查找可回收对象

我们都知道垃圾回收机制是将内存中不可能在被使用的的对象实例(可回收的对象实例)回收释放其所占用的内存,以供其他对象使用。JAVA的垃圾回收机制是对JAVA堆和方法区的内存回收。那么CG是怎么知道该对象是否还会使用呢?

一、引用计数算法(Reference Counting)

引用计数算法简单的讲就是给每个对象中添加一个引用计数器, 每当有一个地方引用它时,计数器值就加1:当引用失效时,计数器值就减1,当对象的计数器为0就表示该对象已“死”,可以被回收了。虽然这种算法实现简单,判定效率也高。但是大部分JAVA虚拟机却没有使用此算法,因为这个算法很难解决对象之间互相循环引用的问题。

二、可达性分析算法(Reachability Analysis)

可达性分析算法是通过被称为 “GC Roots" 的对象作为起始点, 从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连,就是从GC Roots到这个对象不可达时,则证明此对象是不可用的。如图1.1。对象 2、对象 4、对象 6不可到达GC Roots所以会被回收。

图1.1

垃圾收集算法

通过上文我们知道了JVM如何查询需要被回收的对象实例,那么JVM是通过什么方法把对象收回的呢?不同虚拟机回收内存的方法各不相同,主流的方法有标记-清除算法、复制算法、标记-整理算法和分代收集算法。

一、标记-清除算法(Mark-Sweep)

标记-清除算法分为“标记”和“清除”两个阶段:首先标记出所有需要可收的对象,在标记完成后统一回收所有被标记的对象。如上文所介绍,标记过程其实就是找出不可能在被使用的对象实例。如图1.2首先标记出需要被回收的对象,然后将这些对象回收,回收后的状态如图1.3。

回收前状态 图1.2
回收后状态 图1.3

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

二、复制算法(Copying)

复制算法将可用内存容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的这一块的内存空间全部清理掉。这样使得每次GC是对整半个内存区域进行回收,内存分配时也就不用考虑内存碎片等问题,只要移动堆指针,按顺序分配内存即可。这种方式实现简单,运行高效。但是这种算法的代价是将内存缩小为原来的一半,未免太高了一点。复制算法的执行过程如图1.4与图1.5所示。

回收前状态 图1.4
回收后状态 图1.5

三、标记-整理算法(Mark-Compact)

标记-整理算法,标记过程与标记-清除算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动, 然后直接清理掉端边界以外的内存,“标记-整理”算法的过程如图1.6与图1.7所示。

回收前状态 图1.6
回收后状态 图1.7

四、分代收集算法(Generational Colllection)

当前主流虚机的垃圾收集都采用“分代收集”,这种算法并没有什么新的思想,只是根据对象存活周期的不同将内存划分为几块。一般是把JAVA堆分为新生代和老年代(新生代与老年代后续会有文章介绍),这样就可以根据各个年代的特点采用最适当的收集算法。在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。而老年代中因为对象存活率高、所以使用“标记-清除”或者“标记-整理” 算法来进行回收。

更多文章可关注微信公众号:IT鸡窝

jvm垃圾回收机制_干货|JVM垃圾回收机制相关推荐

  1. java垃圾回收机制_笔记 | Java垃圾回收机制

    本文经授权转载自程序员杂货铺(ID:speakFramework) 垃圾回收 最近上海的小伙伴是不是要被强垃圾分类搞疯了???哈哈哈哈 上海是个走在前列的城市啊,不光骑自行车闯红灯要被罚钱,垃圾不分类 ...

  2. python垃圾回收离职_谈谈python垃圾回收机制

    什么是垃圾回收机制? 首先,咱先来解释名词,垃圾回收是不是就是将没用的,废弃的东西回收起来. 在坐的各位都没有女朋友对吧,那难以想象你们的房间会是一个什么样子,可能会有很多垃圾,很凌乱,自己也不收拾. ...

  3. 6种java垃圾回收算法_学习java垃圾回收

    垃圾回收(GC)一直是Java受欢迎背后的重要特性之一.垃圾回收是Java中用于释放未使用的内存的机制.本质上,它追踪所有仍在使用的对象,并将剩下的标记为垃圾.Java的垃圾回收被认为是一种自动内存管 ...

  4. 老年代的更新机制_如何理解Java GC机制

    Java GC机制 简单来说就干了3件事 确定哪些内存需要回收,确定什么时候需要执行GC,如何执行GC 确定哪些内存需要回收 垃圾收集器在对堆进行回收前,第一件事情就是要确定这些对象之中哪些还&quo ...

  5. python内存管理机制_[转] Python内存管理机制

    一.引用计数 1.变量与对象 变量赋值的时候才创建,它可以指向(引用)任何类型的对象 python里每一个东西都是对象,它们的核心就是一个结构体:PyObject 变量必须先赋值,再引用. 比如,你定 ...

  6. java垃圾回收机制_干货:Java 垃圾回收机制

    什么是自动垃圾回收? 自动垃圾回收是一种在堆内存中找出哪些对象在被使用,还有哪些对象没被使用,并且将后者删掉的机制. 所谓使用中的对象(已引用对象),指的是程序中有指针指向的对象:而未使用中的对象(未 ...

  7. python垃圾回收价格表_主流的垃圾回收机制都有哪些?

    常用的垃圾收集算法 目录如下:引用计数法 标记-清除算法(Mark-Sweep) 复制算法(Copying) 标记-整理算法(Mark-compact) 分代收集算法 Generational Col ...

  8. python垃圾回收离职_详细解说python垃圾回收机制

    不同于C/C++,像Python这样的语言是不需要程序员写代码来管理内存的,它的GC(Garbage Collection)机制 实现了自动内存管理.GC做的事情就是解放程序员的双手,找出内存中不用的 ...

  9. 双亲委托类加载机制_图解JVM类加载机制和双亲委派模型

    我们都知道以 .java 结尾的 Java 源文件,经过编译之后会变成 .class 结尾的字节码文件.JVM 通过类加载器来加载字节码文件,然后再执行程序. 什么时候加载一个类 那么,什么时候类加载 ...

最新文章

  1. LeetCode实战:环形链表
  2. 「3」Java开发环境搭建
  3. Everest 0.6 添加开机自启动程序
  4. 什么样的程序员会让人讨厌?大家注意,千万不要成为这种程序员!
  5. 2.12 主成分分析(下)
  6. 怎样剪立体灯笼_教你怎样做新年DIY剪纸拉花灯笼
  7. redis深度历险 pdf_程序员面试必备精选文档:Redis+Ng+Tomcat+并发编程+Spring系列
  8. ASP.NET错误处理的方式(一)
  9. 重走JAVA之路(四):ThreadLocal源码解析
  10. JCR分区与中科院分区详解-中科院基础版和升级版详解
  11. 高仿京东分类页面实现
  12. 最短剩余时间调度算法_LRTF:最长剩余时间优先调度算法
  13. 25~30K的国外企业招聘面试考题,10分钟就能写出来了?
  14. windows系统解决程序端口号被占用
  15. 数学公式截图转Latex格式
  16. 为什么我的程序中没有stdafx.h头文件?
  17. 计算机技术应用社会实践课题,PLC自动化专业社会实践报告.docx
  18. 洛谷P4942 小凯的数字
  19. windows邮箱无法登录腾讯企业邮箱
  20. C++没落了?学习C++没有前途了?从业者给你揭晓答案

热门文章

  1. .net学习笔记----WebConfig常用配置节点介绍
  2. 一个简单WCF项目的建立 by wsz
  3. 调试opengl程序出错
  4. C# 判断一字符串是否为合法数字(正则表达式)
  5. 计算机网络——码元,波特,速率和带宽
  6. 牛客16437 买铅笔
  7. openlayers实例_介绍OpenLayers
  8. python成绩转换、百分制到五分制_设计一个程序,将从键盘上输入的百分制成绩转换成对应的五分制成绩并输出。90分以上为A,80~90分为B,...
  9. python的神经网络编程_Python神经网络编程 第二章 使用Python进行DIY
  10. 计算机仿真在机械行业中的应用,计算机仿真技术机械行业应用