垃圾(Garbage)就是程序需要回收的对象,如果一个对象不在被直接或间接地引用,那么这个对象就成为了「垃圾」,它占用的内存需要及时地释放,否则就会引起「内存泄露」。有些语言需要程序员来手动释放内存(回收垃圾),有些语言有垃圾回收机制(GC),例如我正在学习的Java语言,存在垃圾回收机制。

在学习Java GC 之前,我们需要记住一个单词:stop-the-world 。它会在任何一种GC算法中发生。stop-the-world 意味着JVM因为需要执行GC而停止了应用程序的执行。当stop-the-world 发生时,除GC所需的线程外,所有的线程都进入等待状态,直到GC任务完成。GC优化很多时候就是减少stop-the-world 的发生,缩短因GC线程中断时间,保证程序运行的效率。

第一种  标记清除

标记清除(Mark and Sweep)是最早开发的GC算法。

原理:两次扫描,第一次从根开始将可能被引用的对象进行以递归的方式进行标记标记,第二次将未标记的对象进行回收,回收成功后将标记的引用对象清除标记为下次的GC回收做准备。

GC时间:与存活对象数和程序对象总数有关,因为要对所有对象进行递归查看是否可以进行回收。

思考:如果存活对象的数量少,那么标记阶段的实际标记很少,剩下的全为不在引用的对象,那么标记阶段的效率便会降低,从而整个GC过程的效率也会降低。

标记清除的方式节省内存但是两次扫描需要更多的时间,对于垃圾比例较小的情况占优势。

第二种  复制收集

复制收集(Copy and Collection)会将从根开始被引用的对象复制到另外的空间中去,然后再舍弃掉旧的空间,利用新的空间。

原理:复制收集的方式只需要对对象进行一次扫描。准备一个「新的空间」,从根开始,对对象进行扫,如果存在对这个对象的引用,就把它复制到「新空间中」。一次扫描结束之后,所有存在于「新空间」的对象就是所有的非垃圾对象。

思考:复制收集具有局部性,在复制收集的过程中,会按照对象被引用的顺序将对象复制到新空间中。于是,关系较近的对象被放在距离较近的内存空间的可能性会提高,这叫做局部性。局部性高的情况   下,内存缓存会更有效地运作,程序的性能会提高。

复制收集更快速但是需要额外开辟一块用来复制的内存,对垃圾比例较大的情况占优势。

第三种    引用计数

引用计数是指,针对每一个对象,保存一个对该对象的引用计数,该对象的引用增加,则相应的引用计数增加。如果对象的引用计数为零,则回收该对象。

原理:每个对象中保存该对象的引用计数,当引用发生增减时对计数进行更新,发生时间点:变量赋值、对象内容更新、函数结束(局部变量不再被引用)。当一个对象的引用计数为零时则说明它不再被引用,因此释放相应的内存空间。

思考:引用计数最大的优点就是容易实现。成本小,基本上引用计数为0的时候垃圾会被立即回收,而其他方法难以预测对象的生命周期,垃圾存在的时间都会比这个方法长。这种垃圾回收方式产生的中断时间最短。

但如果对象中存在循环引用,就无法被回收。引用计数不适合在并行中使用,多个线程同时操作引用计数,会引起数值不一样的问题从而导致内存错误。所以引用计数必须采用独占方式,如果引用操作频繁,那么加锁等并发控制机制的开销是相当大的。

Java GC(垃圾回收机制)

JVM GC只回收堆区和方法区内的对象。而栈区的数据,在超出作用域后会被JVM自动释放掉,所以其不在JVM GC的管理范围内。

判定对象是否可回收的标准:

对象没有引用

作用域发生未捕获异常

程序在作用域正常执行完毕

程序执行了System.exit()

程序发生意外终止(被杀线程等)

在Java程序中不能显式的分配和注销缓存,因为这些事情JVM都帮我们做了,那就是GC。

有些时候我们可以将相关的对象设置成null 来试图显示的清除缓存,但是并不是设置为null 就会一定被标记为可回收,有可能会发生逃逸。

将对象设置成null 至少没有什么坏处,但是使用System.gc() 便不可取了,使用System.gc() 时候并不是马上执行GC操作,而是会等待一段时间,甚至不执行,而且System.gc() 如果被执行,会触发Full GC ,这非常影响性能。

Java的垃圾回收是分代回收的,分为三代:新生代,老年代,持久代。

新生代(Young generation):绝大多数最新被创建的对象都会被分配到这里,由于大部分在创建后很快变得不可达,很多对象被创建在新生代,然后“消失”。对象从这个区域“消失”的过程我们称之为:Minor GC 。

老年代(Old generation):对象没有变得不可达,并且从新生代周期中存活了下来,在新生代的战场上奋勇存活下来的对象,是不会轻易狗带的,嘻嘻。会被拷贝到这里。其区域分配的空间要比新生代多。也正由于其相对大的空间,发生在老年代的GC次数要比新生代少得多。对象从老年代中消失的过程,称之为:Major GC 或者 Full GC。

持久代(Permanent generation)也称之为 方法区(Method area):用于保存类常量以及字符串常量。注意,这个区域不是用于存储那些从老年代存活下来的对象,这个区域也可能发生GC。发生在这个区域的GC事件也被算为 Major GC 。只不过在这个区域发生GC的条件非常严苛,必须符合以下三种条件才会被回收:

1、所有实例被回收

2、加载该类的ClassLoader 被回收

3、Class 对象无法通过任何途径访问(包括反射)

新生代和老年代的结构:

新生代空间的构成与逻辑

为了更好的理解GC,我们来学习新生代的构成,它用来保存那些第一次被创建的对象,它被分成三个空间:

· 一个伊甸园空间(Eden)

· 两个幸存者空间(Fron Survivor、To Survivor)

默认新生代空间的分配:Eden : Fron : To = 8 : 1 : 1

每个空间的执行顺序如下:

1、绝大多数刚刚被创建的对象会存放在伊甸园空间(Eden)。

2、在伊甸园空间执行第一次GC(Minor GC)之后,存活的对象被移动到其中一个幸存者空间(Survivor)。

3、此后,每次伊甸园空间执行GC后,存活的对象会被堆积在同一个幸存者空间。

4、当一个幸存者空间饱和,还在存活的对象会被移动到另一个幸存者空间。然后会清空已经饱和的哪个幸存者空间。

5、在以上步骤中重复N次(N = MaxTenuringThreshold(年龄阀值设定,默认15))依然存活的对象,就会被移动到老年代。

从上面的步骤可以发现,两个幸存者空间,必须有一个是保持空的。如果两个两个幸存者空间都有数据,或两个空间都是空的,那一定是你的系统出现了某种错误。

我们需要重点记住的是,对象在刚刚被创建之后,是保存在伊甸园空间的(Eden)。那些长期存活的对象会经由幸存者空间(Survivor)转存到老年代空间(Old generation)。

也有例外出现,对于一些比较大的对象(需要分配一块比较大的连续内存空间)则直接进入到老年代。一般在Survivor 空间不足的情况下发生。

老年代空间的构成与逻辑

老年代空间的构成其实很简单,它不像新生代空间那样划分为几个区域,它只有一个区域,里面存储的对象并不像新生代空间绝大部分都是朝闻道,夕死矣。这里的对象几乎都是从Survivor 空间中熬过来的,它们绝不会轻易的狗带。因此,Full GC(Major GC)发生的次数不会有Minor GC 那么频繁,并且做一次Major GC 的时间比Minor GC 要更长(约10倍)。

linux java gc_Java GC机制及相关相关推荐

  1. gc java root_聊聊Java的GC机制

    原标题:聊聊Java的GC机制 近日,MIUI在小米全球社区发布公告,表示MIUI将在全球市场销售的手机中预装谷歌拨号及谷歌消息应用程序(中国.印度.印度尼西亚等市场除外).小米表示,小米9T Pro ...

  2. Java的GC机制及算法

    转载自   Java的GC机制及算法 GC的阶段  对每个对象而言,垃圾回收分为两个阶段:finalization和reclamation. finalization: 指运行这个对象的finaliz ...

  3. java 避免gc_Java GC机制

    Java GC机制是JVM中一个最重要的部分,了解GC机制也对了解JVM中内存分布,日志查看等原理有所了解 存储划分 垃圾回收算法 1.引用计数(Reference Counting) 2.标记清除( ...

  4. 性能测试瓶颈分析与系统调优(9)java程序GC机制及性能稳定性调优分析

    8.1 jvm资源监控工具 8.1.1jconsole监控工具 jmap:此工具在jdk安装目录的bin文件夹里面 jmap [option]<pid> 例如:jmap -heap 603 ...

  5. java gc 循环引用_JVM(3)对象A和B循环引用,最后会不会不被GC回收?-------关于Java的GC机制...

    ①首先说一下,GC里边在JVM其中是使用的ROOT算法,ROOT算法,什么称作为ROOT呢,就是说类的静态成员,静态成员就是static修饰的那种,是"根"的一个,根还包含方法中的 ...

  6. java gc机制 优点_聊聊Java的GC机制

    作者 某人Valar 如需转载请保留原文链接 部分图片来自百度,如有侵权请联系删除 本文目录 什么是GC JVM内存结构简单介绍 可达性分析与GC Roots 常见的垃圾收集算法 1. 什么是GC G ...

  7. 聊聊Java的GC机制,看了都说好~

    点击上方 "程序员小乐"关注, 星标或置顶一起成长 关注订阅号「程序员小乐」,收看更多精彩内容 每日英文 Past is a nice place to visit, but ce ...

  8. JAVA之JVM GC 机制与性能优化

    1 背景介绍 与C/C++相比,JAVA并不要求我们去人为编写代码进行内存回收和垃圾清理.JAVA提供了垃圾回收器(garbage collector)来自动检测对象的作用域),可自动把不再被使用的存 ...

  9. JAVA垃圾回收机制-史上最容易理解看这一篇就够了

    目录 1. JDK构成 2. JAVA执行过程 2.1 第一步:编译阶段 2.2 第二步:运行阶段 3. JAVA内存管理 3.1 JAVA的内存模型 3.2 JVM1.7和1.8区别 3.3 JAV ...

最新文章

  1. html5 data url,HTML5 / Javascript – DataURL到Blob和Blob到DataURL
  2. 目标检测模型从训练到部署!
  3. 20210810 所有图像数据准备一条龙(labelme_json转mask、数据增强Augmentor、随机种子设比例生成train.val、转格式(.jpg转.png)、尺寸、位深度变换
  4. 切换不了摄像头 高拍仪_手机摄像头模组支架保护膜的变革之路
  5. 营销 | 10个助燃商业增长的市场营销战略!
  6. scrapy 动态IP、随机UA、验证码
  7. c语言选择菜单程序设计,c语言课程设计报告-- 使用菜单选择趣味程序.doc
  8. 网站对战服务器,PVP核心精华:三大服务器对战
  9. WCF 进阶: 对称加密传输
  10. chrome谷歌浏览器截图
  11. 开启MyBatis(一)
  12. 百度html的json解析,百度调用API返回json数据解析
  13. android中屏幕保护的实现的,Android 屏幕保护程序制做及源码
  14. 3DMAX 卸载方法,完美彻底卸载清除干净3DMAX各种残留注册表和文件【转载】
  15. 查看pdf文件的目录和添加标签的方法
  16. 文件下载文件中文名问题
  17. mysql mtq_Mysql常用简介 - osc_r3mtqivi的个人空间 - OSCHINA - 中文开源技术交流社区
  18. Pixelmator for mac(图片编辑处理工具) v3.8.1激活版
  19. Aruba7010 默认密码_工信部提醒:手机要及时设置SIM卡密码!很多人都不知道!...
  20. 稀疏特征(稀疏矩阵)

热门文章

  1. 2014年去哪儿网笔试题--一个10*10的矩阵(可以理解为棋盘),随时生成一组数据填入矩阵,任何一个位置的数字除4进行计算,按余数着色......
  2. 打开一个页面,并监听该页面的关闭事件
  3. petshop4.0 详解之七(PetShop表示层设计)
  4. 虚拟机下安装ubuntu
  5. WebFlux系列(十)WebClient 异常处理
  6. 算法工程师面试备战笔记1_如何处理特征向量的缺失值
  7. 跨越『时空』的难样本挖掘!
  8. 【论文】Awesome Relation Extraction Paper(关系抽取)(PART III)
  9. 吉林大学计算机专业宿舍研究生,吉林大学计算机系的研究生宿舍怎么样?我想考那的..._在职考研_帮考网...
  10. cocos2d for android,cocos2d-x for android