任何语言在运行过程中都会创建对象,也就意味着需要在内存中为这些对象在内存中分配空间,在这些对象失去使用的意义的时候,需要释放掉这些内容,保证内存能够提供给新的对象使用。对于对象内存的释放就是垃圾回收机制,也叫做gc,对于java开发者来说gc是一个双刃剑 我们这里找了两张搞笑图片分别来表示c语言的垃圾回收和 java的垃圾回收。 注意:并不是说谁好谁坏,只是一个调侃图。

c语言:

java语言:

c的垃圾回收是人工的,工作量大,但是可控性高。 java是自动化的,但是可控性很差,甚至有时会出现内存溢出的情况, 内存溢出也就是jvm分配的内存中对象过多,超出了最大可分配内存的大小。

``` 提到java的垃圾回收机制就不得不提一个方法:

System.gc()用于调用垃圾收集器,在调用时,垃圾收集器将运行以回收未使用的内存空间。它将尝试释放被丢弃对象占用的内存。  然而System.gc()调用附带一个免责声明,无法保证对垃圾收集器的调用。  所以System.gc()并不能说是完美主动进行了垃圾回收。 作为java程序员还是很有必要了解一下gc,这也是面试过程中经常出现的一道题目。  

我们从三个角度来理解gc:

1jvm怎么确定哪些对象应该进行回收

2jvm会在什么时候进行垃圾回收的动作

3jvm到底是怎么清楚垃圾对象的

jvm怎么确定哪些对象应该进行回收

对象是否会被回收的两个经典算法:引用计数法,和可达性分析算法

引用计数法

简单的来说就是判断对象的引用数量。实现方式:给对象共添加一个引用计数器,每当有引用对他进行引用时,计数器的值就加1,当引用失效,也就是不在执行此对象是,他的计数器的值就减1,若某一个对象的计数器的值为0,那么表示这个对象没有人对他进行引用,也就是意味着是一个失效的垃圾对象,就会被gc进行回收。  但是这种简单的算法在当前的jvm中并没有采用,原因是他并不能解决对象之间循环引用的问题。  假设有A和B两个对象之间互相引用,也就是说A对象中的一个属性是B,B中的一个属性时A,这种情况下由于他们的相互引用,从而是垃圾回收机制无法识别。

因为引用计数法的缺点有引入了可达性分析算法,通过判断对象的引用链是否可达来决定对象是否可以被回收。可达性分析算法是从离散数学中的图论引入的,程序把所有的引用关系看作一张图,通过一系列的名为GC Roots的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链。当一个对象到 GC Roots 没有任何引用链相连(就是从 GC Roots 到这个对象不可达)时,则证明此对象是不可用的。 如图:

二在确定了哪些对象可以被回收之后

jvm会在什么时候进行回收

1会在cpu空闲的时候自动进行回收  2在堆内存存储满了之后  3主动调用System.gc()后尝试进行回收

三如何回收

如何回收说的也就是垃圾收集的算法。

算法又有四个:标记-清除算法,复制算法,标记-整理算法,分代收集算法.    

1 标记-清除算法。这是最基础的一种算法,分为两个步骤,第一个步骤就是标记,也就是标记处所有需要回收的对象,标记完成后就进行统一的回收掉哪些带有标记的对象。这种算法优点是简单,缺点是效率问题,还有一个最大的缺点是空间问题,标记清除之后会产生大量不连续的内存碎片,当程序在以后的运行过程中需要分配较大对象时无法找到足够的连续内存而造成内存空间浪费。执行如图:

2复制算法。 复制将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。这样使得每次都是对其中的一块进行内存回收,内存分配时也就不用考虑内存碎片等复杂情况。只是这种算法的代价是将内存缩小为原来的一半。复制算法的执行过程如图:

复制收集算法在对象存活率较高时就要执行较多的复制操作,效率将会变低。更关键的是,浪费了一半的空间。标记-整理算法: 标记整理算法与标记清除算法很相似,但最显著的区别是:标记清除算法仅对不存活的对象进行处理,剩余存活对象不做任何处理,造成内存碎片;而标记整理算法不仅对不存活对象进行处理清除,还对剩余的存活对象进行整理,重新整理,因此其不会产生内存碎片。标记整理算法的作用示意图如下:

分代收集算法: 分代收集算法是一种比较智能的算法,也是现在jvm使用最多的一种算法,他本身其实不是一个新的算法,而是他会在具体的场景自动选择以上三种算法进行垃圾对象回收。那么现在的重点就是分代收集算法中说的自动根据具体场景进行选择。这个具体场景到底是什么场景。 场景其实指的是针对jvm的哪一个区域,1.7之前jvm把内存分为三个区域:新生代,老年代,永久代。

了解过场景之后再结合分代收集算法得出结论: 1、在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就选用复制算法。只需要付出少量存活对象的复制成本就可以完成收集。 2、老年代中因为对象存活率高、没有额外空间对他进行分配担保,就必须用标记-清除或者标记-整理。总结:

注意: 在jdk8的时候java废弃了永久代,但是并不意味着我们以上的结论失效,因为java提供了与永久代类似的叫做“元空间”的技术。 废弃永久代的原因:由于永久代内存经常不够用或发生内存泄露,爆出异常java.lang.OutOfMemoryErroy。元空间的本质和永久代类似。不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。也就是不局限与jvm可以使用系统的内存。理论上取决于32位/64位系统可虚拟的内存大小。

转载于:https://www.cnblogs.com/summary-2017/p/9594026.html

java中的垃圾回收机相关推荐

  1. Java中的垃圾回收与对象生命周期

    转载自   Java中的垃圾回收与对象生命周期 1. 垃圾回收 垃圾回收是Java程序设计中内存管理的核心概念,JVM的内存管理机制被称为垃圾回收机制. 一个对象创建后被放置在JVM的堆内存中,当永远 ...

  2. 【java虚拟机序列】java中的垃圾回收与内存分配策略

    在[java虚拟机系列]java虚拟机系列之JVM总述中我们已经详细讲解过java中的内存模型,了解了关于JVM中内存管理的基本知识,接下来本博客将带领大家了解java中的垃圾回收与内存分配策略. 垃 ...

  3. 一篇文章搞定java中的垃圾回收机制面试题

    一篇文章搞定java中的垃圾回收机制面试题 任何语言在运行过程中都会创建对象,也就意味着需要在内存中为这些对象在内存中分配空间,在这些对象失去使用的意义的时候,需要释放掉这些内容,保证内存能够提供给新 ...

  4. Java中的垃圾回收

    转载自http://www.wolfbe.com/detail/201609/365.html GC算法基础 摘要:研究人员发现应用中绝大多数的内存分配会分为两大类:绝大部分的对象很快会变为不可用状态 ...

  5. [转载] Python和java中的垃圾回收机制

    参考链接: Python中的垃圾回收 Python的垃圾回收机制 Python的垃圾回收机制有两种(也可以说一种:叫引用计数): 一是引用计数, 二是隔代回收. 引用计数 引用计数原理: 当数据的引用 ...

  6. 第八章软件构造的性能——构造性能的度量、原则与方法(java中的垃圾回收机制及算法)

    这节内容真的是多到炸裂,而且全都是概念,不过很挺有用的,学完这节会对内存管理有一个比较深的理解和认识,就是--这也太多了--嘤嘤嘤T_T 1.性能度量(performance metrics) 第一点 ...

  7. JAVA中的垃圾回收机制以及其在android开发中的作用

    http://blog.csdn.net/xieqibao/article/details/6707519 这篇文章概述了JAVA中运行时数据的结构,以及垃圾回收机制的作用.在后半部分,描述了如何检测 ...

  8. Java中的垃圾回收原理

    用户程序(mutator)会修改还堆区中的对象集合,从存储管理器处获取空间,创建对象,还可一引入和消除对已有对象的引用. 当mutator不能"达到"某些对象的时候,这些对象就成了 ...

  9. java中的垃圾回收算法

    java中有四种垃圾回收算法,分别是: 标记清除法.标记整理法.复制算法.分代收集算法 1.标记清除法: 第一步:利用可达性去遍历内存,把存活对象和垃圾对象进行标记; 第二步:在遍历一遍,将所有标记的 ...

最新文章

  1. CSS3 稳固而知新: 居中
  2. 解题报告 『[NOI2014]起床困难综合症』
  3. cc、gcc、g++ 的区别和联系
  4. GDCM:处理(各种操作处理)DICOM图像文件的测试程序
  5. java 移动页面中的图片上传_HTML5移动端图片上传(一)
  6. 全志和瑞芯微比较_哪家强_全志瑞芯微海思PK 智能芯片哪家强?
  7. 金融系统中正确的金额计算及存储方式
  8. 下载android版趣步最新版,趣步下载2021安卓最新版_手机app官方版免费安装下载_豌豆荚...
  9. 数据结构——排序算法
  10. Nginx中的break和last
  11. 蔚来汽车发布声明:自称“前员工”造谣者已被起诉 查明并非前员工
  12. .NET中的DES对称加密
  13. g++能过,c++过不了
  14. NUC1154 Vertical Histogram【打印图案】
  15. Camtasia Recorder 2020如何确定录制区域
  16. 101—200之间的素数-Java编写
  17. 企业架构-数据服务总线思路
  18. 微信自动回复 html 点击文字,常见微信自动回复经典语录
  19. 推荐几款视频声音变声软件给大家
  20. 怎么调整电脑的鼠标的灵活度

热门文章

  1. bootstrap 空行不显示横杠_bootstrap兼容问题
  2. python可选参数定义_c#教程之定义可选参数
  3. mysql binlog 备份_偷偷的删表删库,跑路之前,尝试用binlog恢复MySQL数据
  4. 邓西百度网盘批量转存检测工具 v1.0.0818
  5. 全开源新淘商城系统源码
  6. Amazon Web Service 雲端運算平台攻略 【2】
  7. ASP.Net2.0小技巧 保持滚动条的位置 焦点移动到某个控件 $符号轻松的使用FindControl...
  8. jquery 鼠标移动 div内容上下或左右滚动
  9. Linux: find和xargs用法整理
  10. 集成方法(随机森林)