当前位置: 首页 > news >正文

java虚拟机(三)java的垃圾回收机制详解

java中的垃圾回收算法是如何确认哪些对象是活的,哪些对象是死的?

对于判断对象是活是死,有两种不同的算法可以运用:

引用计数算法:

给对象中添加一个引用计数器,如果有一个地方引用他,计数值就加一,当引用失效后,计数值就减一。每次进行垃圾回收时,将那些引用计数器值为0的对象回收,这就是引用计数算法。但是java语言并没有选择这种算法,原因是当两个对象相互引用时,引用计数器的值永远不会等于0,而这里的对象如果不被使用就理应是垃圾。

objA.instance=objB; objB.instance=objA;

根搜索算法:

根搜索算法是主流的面向对象程序语言中用来判定对象是否存活的算法,也是目前主流java虚拟机所用到的垃圾回收算法。

基本思路:通过一系列名为"GC Roots"的对象作为起始点,从这些节点向下搜索,搜索的路径称为引用链,如果一个对象没有和任何引用链相连,就说明这个对象是没有用的,就是可以回收的对象。

可作为GC Root的对象:

1.虚拟机栈中引用的对象

2.方法区中的类静态属性引用的对象

3.方法区中的常量引用的对象

4.本地方法栈中JNI的引用的对象

关于引用:

从刚开始学java的时候,我的老师就告诉我java中到处都是引用,同样判断对象是否可以回收也和引用有关系。在java中有四种引用:

强引用(Strong):强引用是我们最常用到的,也是程序中最普遍存在的,如

Object obj=new Object();

软引用(soft):软引用是那些还有用,但非必要的对象。当系统的内存即将要溢出时,软引用的对象会被当成可以回收的对象。java中提供了SoftReference类实现软引用

弱引用(Weak):弱引用的强度比软引用更弱一些,被弱引用关联的对象只能生存到下一次垃圾收集发生之前,当垃圾收集器工作时,无论当前内存是否足够,都会回收掉植被弱引用关联的对象。java中提供WeakReference类来实现弱引用

虚引用(Phantom):这个英文单词的意思是幽灵的意思,因此虚引用也被称为幽灵引用,它是最弱的一种引用。无法通过虚引用来取得一个对象实例,为一个对象设置虚引用关联的唯一目的就是当这个对象被回收时收到一个系统通知,java提供PhantomReference类来实现虚引用。

方法区的垃圾回收:

我们都知道java创建的对象都放在虚拟机的堆中,GC也主要发生在Heap中。对于方法区要不要进行垃圾回收也是一个问题,java虚拟机规范中说可以不要求虚拟机在方法区实现垃圾回收,因为在方法区进行垃圾回收性价比很低。在堆中,尤其是在新生代中,一次垃圾回收可以回收70%-95%的空间,但是在方法区中效率很低。

方法区需要回收的主要是废弃常量和无用的类,以常量为例,当一个字符串常量已经进入常量池,且没有任何对象引用这个常量,这个时候,可以对这个常量进行回收。

虽然java虚拟机规范中说明可以不回收方法区的垃圾,但是在大量使用反射、动态代理,CGLib等场景,以及动态生成JSP等频繁自定义ClassLoader等场景都需要虚拟机对方法区进行回收,以防止永生代的溢出。

垃圾收集算法:

不同的虚拟机所采用的垃圾收集算法各不相同,介绍几种常用的垃圾收集算法实现原理:

标记-清除算法:

最基础的收集算法,分为标记和清除两个阶段,首先标记处需要回收的对象,在某个时间点统一收集被标记的对象,但是缺点也很明显,标记和清除过程的效率都不高;标记清除后会产生大量不连续的内存碎片。

复制算法:

复制算法将内存按容量分为大小相同的两块,每次只使用其中一块,当这一块的内存用完之后,就将还存活的对象复制到另外一块上,把已经使用的内存空间一次性处理掉。这样就不需要考虑内存碎片的问题。缺点是可用内存变成了原来的一半,代价十分高。

但其实内存的划分不需要按照1:1来分,新生代中的对象有98%是会被回收的,现在的虚拟机很多都是采用这种算法实现垃圾收集。将新生代的内存分为一块Eden空间和两块Survivor空间,比例为8:1:1,当一个对象刚创建时,会进入Eden空间,一次GC还存活的对象会进入Survivor,每存活一次岁数就加1,等加到一定岁数这个对象就会进入老年代。因为新生代对象的回收率很高,所以每次把Eden和其中一块Survivor中存活的对象放到另一块对象中,再把清理这两块内存中的对象,这样浪费的空间只占10%,远远小于刚才的50%。因为不能保证存活的对象总小于10%,所以还需要老年代的内存进行分配担保,当存活对象大于10%时,需要借用老年代的内存。

标记-整理算法:

这个算法的过程和标记-清除算法类似,只不过在标记完之后不是立刻清除,而是把存活的对象都往一侧移动,然后再清除掉边界之外的对象

相关文章:

  • 查看ORACLE的实际执行计划
  • 开发基于SpringBoot和BootStrap的全栈论坛网站(三):登陆注册以及cookies的功能完成
  • 开发基于SpringBoot和BootStrap的全栈论坛网站(四):完成问题发布功能
  • OSChina 周日乱弹 ——冯小牛 我要治愈你!
  • 开发基于SpringBoot和BootStrap的全栈论坛网站(五):完成首页展示以及分页功能
  • 冒泡排序法与二分查找法
  • github回退版本时本地代码被覆盖(已解决)
  • CentOS 6.5系统上安装SVN服务器端的方法及目录访问权限配置(转总结)
  • 开发基于SpringBoot和BootStrap的全栈论坛网站(六):完成个人中心、问题详情和问题编辑
  • 开发基于SpringBoot和BootStrap的全栈论坛网站(七):完成回复和二级回复功能
  • 项目管理过程 工作绩效数据,信息和报告
  • 开发基于SpringBoot和BootStrap的全栈论坛网站(八):完成回复通知的功能
  • 架构师
  • SpringCloud微服务入门:使用idea搭建第一个微服务项目(附源码)
  • 图文详解YUV420数据格式
  • 【跃迁之路】【477天】刻意练习系列236(2018.05.28)
  • 2018天猫双11|这就是阿里云!不止有新技术,更有温暖的社会力量
  • bootstrap创建登录注册页面
  • C++11: atomic 头文件
  • javascript 哈希表
  • js递归,无限分级树形折叠菜单
  • PermissionScope Swift4 兼容问题
  • 浮动相关
  • 解决jsp引用其他项目时出现的 cannot be resolved to a type错误
  • 每个JavaScript开发人员应阅读的书【1】 - JavaScript: The Good Parts
  • 面试总结JavaScript篇
  • 嵌入式文件系统
  • 深度学习中的信息论知识详解
  • 说说动画卡顿的解决方案
  • 详解NodeJs流之一
  • 一、python与pycharm的安装
  • 怎么把视频里的音乐提取出来
  • 自定义函数
  • ​软考-高级-系统架构设计师教程(清华第2版)【第12章 信息系统架构设计理论与实践(P420~465)-思维导图】​
  • ​水经微图Web1.5.0版即将上线
  • # C++之functional库用法整理
  • # 透过事物看本质的能力怎么培养?
  • #NOIP 2014#day.2 T1 无限网络发射器选址
  • #中的引用型是什么意识_Java中四种引用有什么区别以及应用场景
  • ${factoryList }后面有空格不影响
  • (2/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  • (HAL库版)freeRTOS移植STMF103
  • (编程语言界的丐帮 C#).NET MD5 HASH 哈希 加密 与JAVA 互通
  • (二)构建dubbo分布式平台-平台功能导图
  • (没学懂,待填坑)【动态规划】数位动态规划
  • (每日持续更新)jdk api之FileReader基础、应用、实战
  • (免费领源码)Java#ssm#MySQL 创意商城03663-计算机毕业设计项目选题推荐
  • (转)LINQ之路
  • * CIL library *(* CIL module *) : error LNK2005: _DllMain@12 already defined in mfcs120u.lib(dllmodu
  • ***原理与防范
  • .“空心村”成因分析及解决对策122344
  • .java 指数平滑_转载:二次指数平滑法求预测值的Java代码
  • .mysql secret在哪_MySQL如何使用索引
  • .NET Core、DNX、DNU、DNVM、MVC6学习资料
  • .Net 中的反射(动态创建类型实例) - Part.4(转自http://www.tracefact.net/CLR-and-Framework/Reflection-Part4.aspx)...