热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

window更新产生的垃圾_11JVM垃圾回收(上)

引用计数法和可达性分析垃圾回收,就是将已经分配出去的,但却不在使用的内存回收回来,以便再次分配。在Java虚拟机语境下,垃圾
42245341ea905799170010c066159418.png

引用计数法和可达性分析

垃圾回收,就是将已经分配出去的,但却不在使用的内存回收回来,以便再次分配。在 Java 虚拟机语境下,垃圾指的是死亡的对象所占据的堆空间。下面就总结一下如何如何辨别一个对象是否死亡。

引用计数法:为每一个对象添加一个引用计数器,用来统计指向该对象的引用个数。如果某个对象的引用计数器为 0,则说明该对象已经死亡,便可以被回收了。

通过引用计数法来标记对象的死亡和存活的过程中,我们需要截获所有引用更新操作,并且相应的增减目标对象的引用计数器。这种方式除了需要额外的空间来存储计数器,以及繁琐的更新操作,引用计数法还有一个重大的漏洞:无法处理循环引用对象。比如:对象 A,B 互相引用,但是除此之外没有其他引用指向 A 或者 B。这种情况下 A,B 其实已经死亡,但是因为存在引用,所以不会被垃圾回收,造成内存泄露。

可达性分析:将一系列 GC Roots 作为初始存活对象集合,然后从该集合出发,探索所有能够被该集合引用的对象,并将其加入到该集合中,这个过程就是标记。标记的对象就是存活对象,未标记到的就是死亡的对象。

什么是 GC Roots 呢?可以暂时理解为由堆外指向堆内的引用,常见的有以下几种: 1:Java 方法栈帧中的局部变量 2:已加载的类的静态变量 3:JNI handles 4:已启动且未停止的 Java 线程

可达性分析解决了引用计数法无法检测循环引用的问题,但是本身也有自己的问题需要解决。比如在多线程环境下,其他线程可能会更新已经访问过的对象中的引用,从而造成误报(将引用设置为 null)或者漏报(将引用设置为未被访问过的对象)。

误报:导致新产生的垃圾对象未被回收。 漏报:导致原程序访问已经被回收的对象,可能导致 Java 虚拟机直接崩溃。

Stop-the-world 以及安全点

为了解决上述问题,在 Java 虚拟机里,采用 Stop-the-world 方式,停止其他非垃圾回收线程的工作,直到完成垃圾回收。这也造就了垃圾回收所谓的暂停时间 GC pause。

Java 虚拟机中的 Stop-the-world 是通过安全点(safepoint)机制来实现的。当 Java 虚拟机收到 Stop-the-world 请求时,它便会等待所有的线程到达安全点,才允许请求 Stop-the-world 的线程进行独占的工作。

安全点的作用不是让线程停下,而是找到让线程找到一个稳定的执行状态。在这个状态下,Java 虚拟机的堆栈不会发生变化。这样,垃圾回收期便能够安全地执行可行性分析。

垃圾回收的三种方式

第一种:清除。 把死亡对象所占据的内存标记为空闲内存,并记录在一个空闲列表中。当需要创建对象时,内存管理块便会从该空闲列表中寻找空闲内存,并划分给新建对象。

这种方式简单明了,但是却有两个缺点。第一:造成内存碎片。由于 Java 虚拟机的堆中对象必须是连续分布的,因此可能出现总空闲内存足够,但是无法分配的极端情况。第二:分配效率低。如果是连续的内存空间,可以通过指针加法来做分配。而对于这种空闲列表,Java 虚拟机则需要住个访问列表中的项,来查找能够存放入新建对象的空闲内存。

第二种:压缩。 把存活的对象聚集到内存区域的起始位置,从而留下一段连续的内存空间。这种做法解决了内存碎片化的问题,但是代价却是压缩算法的性能开销。

第三种:复制。 内存区域分为两等分,分别用两个指针 from 和 to 来维护,并且只是用 from 指针指向的内存区域来分配内存。当发生垃圾回收时,把存活的对象复制到 to 指针指向的内存区域,并且交换 from 指针和 to 指针的内容。这种方法同样解决了内存碎片化的问题,但是堆空间的使用效率及其地下,只用到了一半。

问答

Q:可达性分析a与b互为引用,这不是死循环了吗,为什么能被回收的

因为可达性分析只标记可达的,如果a和b都不可达,那么可达性分析标记不到,就当成垃圾回收了。

Q:对于为什么需要stw机制的解释还是有的困惑。假如一个对象已经被标记为垃圾了,其它线程怎么还会有机会引用它呢?就算通过stw,把它标记并回收了,那想引用它的线程重新恢复执行了会发生什么?

GC标记的是活着的(能够被引用到的)对象,剩下的是垃圾。如果没有STW,其他线程在垃圾回收过程中产生了垃圾(某对象不再被引用),那么会被漏掉。

总结

本文创作灵感来源于 极客时间 郑雨迪老师的《深入拆解 Java 虚拟机》课程,通过课后反思以及借鉴各位学友的发言总结,现整理出自己的知识架构,以便日后温故知新,查漏补缺。

关注本人公众号,第一时间获取最新文章发布,每日更新一篇技术文章。

a0e89fc342ea375f554a8865eeaaef0e.png



推荐阅读
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 浏览器中的异常检测算法及其在深度学习中的应用
    本文介绍了在浏览器中进行异常检测的算法,包括统计学方法和机器学习方法,并探讨了异常检测在深度学习中的应用。异常检测在金融领域的信用卡欺诈、企业安全领域的非法入侵、IT运维中的设备维护时间点预测等方面具有广泛的应用。通过使用TensorFlow.js进行异常检测,可以实现对单变量和多变量异常的检测。统计学方法通过估计数据的分布概率来计算数据点的异常概率,而机器学习方法则通过训练数据来建立异常检测模型。 ... [详细]
  • 背景应用安全领域,各类攻击长久以来都危害着互联网上的应用,在web应用安全风险中,各类注入、跨站等攻击仍然占据着较前的位置。WAF(Web应用防火墙)正是为防御和阻断这类攻击而存在 ... [详细]
  • 腾讯安全平台部招聘安全工程师和数据分析工程师
    腾讯安全平台部正在招聘安全工程师和数据分析工程师。安全工程师负责安全问题和安全事件的跟踪和分析,提供安全测试技术支持;数据分析工程师负责安全产品相关系统数据统计和分析挖掘,通过用户行为数据建模为业务决策提供参考。招聘要求包括熟悉渗透测试和常见安全工具原理,精通Web漏洞,熟练使用多门编程语言等。有相关工作经验和在安全站点发表作品的候选人优先考虑。 ... [详细]
  • Windows7企业版怎样存储安全新功能详解
    本文介绍了电脑公司发布的GHOST WIN7 SP1 X64 通用特别版 V2019.12,软件大小为5.71 GB,支持简体中文,属于国产软件,免费使用。文章还提到了用户评分和软件分类为Win7系统,运行环境为Windows。同时,文章还介绍了平台检测结果,无插件,通过了360、腾讯、金山和瑞星的检测。此外,文章还提到了本地下载文件大小为5.71 GB,需要先下载高速下载器才能进行高速下载。最后,文章详细解释了Windows7企业版的存储安全新功能。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 本文介绍了Java的集合及其实现类,包括数据结构、抽象类和具体实现类的关系,详细介绍了List接口及其实现类ArrayList的基本操作和特点。文章通过提供相关参考文档和链接,帮助读者更好地理解和使用Java的集合类。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • CentOS 7部署KVM虚拟化环境之一架构介绍
    本文介绍了CentOS 7部署KVM虚拟化环境的架构,详细解释了虚拟化技术的概念和原理,包括全虚拟化和半虚拟化。同时介绍了虚拟机的概念和虚拟化软件的作用。 ... [详细]
author-avatar
黑马@梦想
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有