又到周末啦,祝各位小伙伴有个愉快的周末。同时也不要忘了学习,上班的同伴们可以利用这两天的时间好好提升自己,在读书的小伙伴们也可以慢慢整理这一周所学到的东西。很多情况下我们看到对自己有用的东西都会保存起来,或者做个笔记,但是很少会再次去翻阅。我们一直在前行,包囊不断获得新东西,但不知不觉得也丢下了我们以为还在的东西!

好啦,道理讲完啦,我们进入主题吧!上一章我们讲到了标记,但是不是被标记了就肯定会被回收呢?不知道小伙伴们记不记得Object类有一个finalize()方法,所有类都继承了Object类,因此也默认实现了这个方法。

finalize的工作原理应该是这样的:一旦垃圾收集器准备好释放对象占用的存储空间,它首先调用finalize(),而且只有在下一次垃圾收集过程中,才会真正回收对象的内存.所以如果使用finalize(),就可以在垃圾收集期间进行一些重要的清除或清扫工作.

finalize()在什么时候被调用?
有三种情况
1.所有对象被Garbage Collection时自动调用,比如运行System.gc()的时候.
2.程序退出时为每个对象调用一次finalize方法。
3.显式的调用finalize方法

这个方法的用途就是:在该对象被回收之前,该对象的finalize()方法会被调用。这里的回收之前指的就是被标记之后,问题就出在这里,有没有一种情况就是原本一个对象开始不再上一章所讲的“关系网”(引用链)中,但是当开发者重写了finalize()后,并且将该对象重新加入到了“关系网”中,也就是说该对象对我们还有用,不应该被回收,但是已经被标记啦,怎么办呢?

针对这个问题,虚拟机的做法是进行两次标记,即第一次标记不在“关系网”中的对象。第二次的话就要先判断该对象有没有实现finalize()方法了,如果没有实现就直接判断该对象可回收;如果实现了就会先放在一个队列中,并由虚拟机建立的一个低优先级的线程去执行它,随后就会进行第二次的小规模标记,在这次被标记的对象就会真正的被回收了。我们来看下面的代码:

大家觉得他会输出什么?最后的结果是:

我被调用啦

我还活着

我挂啦

有木有觉得很诧异,明明调用了两次同样的方法,但输出怎么不同呢?而且明明调用了两次gc()方法(这里确认是执行了gc),那怎么只进入了一次finalize()方法?

嘿嘿,其实面对同一个对象,他的finalize()方法只会被调用一次,因此第一次调用的时候会进行finalize()方法,并且成功的将该对象加入了“关系网”中,但当第二次回收的时候并不会进入,所以第二次不能将对象加入“关系网”中,导致被回收了。

图中有一行让程序睡眠一秒钟的代码,为的就是确保让低优先级的执行finalize()方法线程执行完成。那如果我们把他注释了会怎样呢?输出结果是:

我挂啦

我被调用啦

我挂啦

很奇怪吧,不过如果执行很多次的话,也会出现最开始那样的结果,但多数会是这个结果。因为我们已经说了,执行finalize()的是一个低优先级的线程,既然是一个新的线程,虽然优先级低了点,但也是和垃圾收集器并发执行的,所以垃圾收集器没必要等这个低优先级的线程执行完才继续执行。也就是说,finalize()方法不一定会在对象第一次标记后执行。用一句清晰易懂的话来说就是:虚拟机确实有调用方法的动作,但是不会确保在什么时候执行完成。因此也就出现了上面输出的结果,对象被回收之后,那个低优先级的线程才执行完。

讲到这里,堆相关的知识也就大概讲完了,讲了好几章。我们时常Mark,是时候停下来整理这些Mark了!

长按下方二维码获得更多猛料干货,觉得写得还不错的话就分享给大家吧!

阅读 7

3投诉

JAVA 鲜为人知的二次标记 第六节的更多相关文章

  1. Java基础知识二次学习--第六章 常用类

    第六章 常用类   时间:2017年4月26日16:14:49~2017年4月26日16:56:02 章节:06章_01节~06章_06节 视频长度:20:57+1:15+8:44+1:26+11:2 ...

  2. (转)Java回收对象的标记 和 对象的二次标记过程

    Java回收对象的标记 和 对象的二次标记过程 二次标记 针对这个问题,虚拟机的做法是进行两次标记,即第一次标记不在“关系网”中的对象.第二次的话就要先判断该对象有没有实现finalize()方法了, ...

  3. 浅谈Java回收对象的标记和对象的二次标记过程_java - JAVA

    文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 一.对象的标记 1.什么是标记?怎么标记? 第一个问题相信大家都知道,标记就是对一些已死的对象打上记号,方便垃圾收集器的 ...

  4. Java开发学习(二十六)----SpringMVC返回响应结果

    SpringMVC接收到请求和数据后,进行了一些处理,当然这个处理可以是转发给Service,Service层再调用Dao层完成的,不管怎样,处理完以后,都需要将结果告知给用户. 比如:根据用户ID查 ...

  5. ASP.NET MVC深入浅出(被替换) 第一节: 结合EF的本地缓存属性来介绍【EF增删改操作】的几种形式 第三节: EF调用普通SQL语句的两类封装(ExecuteSqlCommand和SqlQuery ) 第四节: EF调用存储过程的通用写法和DBFirst模式子类调用的特有写法 第六节: EF高级属性(二) 之延迟加载、立即加载、显示加载(含导航属性) 第十节: EF的三种追踪

    ASP.NET MVC深入浅出(被替换)   一. 谈情怀-ASP.NET体系 从事.Net开发以来,最先接触的Web开发框架是Asp.Net WebForm,该框架高度封装,为了隐藏Http的无状态 ...

  6. Java设计模式(二) 工厂方法模式

    本文介绍了工厂方法模式的概念,优缺点,实现方式,UML类图,并介绍了工厂方法(未)遵循的OOP原则 原创文章.同步自作者个人博客 http://www.jasongj.com/design_patte ...

  7. Java入门(二)——果然断更的都是要受惩罚的。。。

    断更了一个多月,阅读量立马从100+跌落至10-,虽说不是很看重这个,毕竟只是当这个是自己的学习笔记,但有人看,有人评论,有人认同和批评的感觉还是很巴适的,尤其以前有过却又被剥夺的,惨兮兮的. 好好写 ...

  8. JAVA GC之标记 第五节

    JAVA GC之标记  第五节 OK,我们继续昨天最后留下的问题,什么是标记?怎么标记? 第一个问题相信大家都知道,标记就是对一些已死的对象打上记号,方便垃圾收集器的清理. 至于怎么标记,一般有两种方 ...

  9. Lucene.Net 2.3.1开发介绍 —— 二、分词(六)

    原文:Lucene.Net 2.3.1开发介绍 -- 二.分词(六) Lucene.Net的上一个版本是2.1,而在2.3.1版本中才引入了Next(Token)方法重载,而ReusableStrin ...

随机推荐

  1. DSP TMS320C6000基础学习(1)——介绍

    主要内容 1. Why process signals digitally? (1)模拟电路由模拟组件构成:电阻.电容及电感等,这些组件随着电压.温度或机械结构的改变会动态影响到模拟电路的效果: (2 ...

  2. PhoneGap或者Cordova框架下实现Html5中JS调用Android原生代码

    PhoneGap或者Cordova框架下实现Html5中JS调用Android原生代码 看看新闻网>看引擎>开源产品 0人收藏此文章, 发表于8小时前(2013-09-06 00:39) ...

  3. Ror初学笔记

    Ror正在以惊人的速度增长着,特别是在常常光顾JavaEye的时候发现Ror已经在国内有非常好的基础了,当然要凑个热闹尝尝鲜 咯. 眼下国内Ror的中文资料还是非常少的,到网上找找就仅仅有Eiffel ...

  4. SQL语言学习-数据定义语言

    Sql语言至今已经有6个版本.SQL查询语言包括了所有对数据的操作命令,这些操作可分为四类:数据定义语言(DDL).数据操纵语言(DML).数据控制语言(DCL)和嵌入式SQL语言. 数据定义语言(D ...

  5. Java日志管理

    首页 资讯 精华 论坛 问答 博客 专栏 群组 更多 ▼ 您还未登录 ! 登录 注册 JavaCrazyer的ItEye(codewu.com)技术博客   博客 微博 相册 收藏 留言 关于我   ...

  6. TCP/IP详解之:TCP

    第17章 TCP:传输控制协议 TCP提供了一种可靠的面向连接的字节流运输层服务 TCP的服务 尽管TCP和UDP都使用相同的网络层(IP),TCP却向应用层提供与UDP完全不同的服务. TCP通过下 ...

  7. HDU1789(Doing Homework again)题解

    HDU1789(Doing Homework again)题解 以防万一,题目原文和链接均附在文末.那么先是题目分析: [一句话题意] 给定任务分数和其截止日期,每日可完成一任务,输出当罚分尽可能小时 ...

  8. Repeater控件实现数据绑定,并实现分页效果

    前台显示代码 <pre name="code" class="csharp"><asp:Repeater ID="Repeater1 ...

  9. PHP面试题之小杂鱼

    这里的题目都是比较老的,但是做笔试题时经常碰到,因为这些题目比较凌乱,考的知识点不好分类,就放一块了 /** * 题目:最少代码实现求3个数的最大值 * 三目运算符实现 */ function get ...

  10. Google机器学习教程心得(一)

    Hello world Google Machine Learning Recipes 1 官方中文博客 http://chinagdg.org/2016/03/machine-learning-re ...