位置: IT常识 - 正文

常见的垃圾回收机制(常见的垃圾回收器有哪些)

编辑:rootadmin
如何工作 在某些 Java 虚拟机中,堆的实现截然不同:它更像一个传送带,每分配一个新对象,它就向前移动一格。 这意味着对象存储空间的分配速度特别快。Java 的"堆指针"只是简单地移动到尚未分配的区域,所以它的效率与 C++ 在栈上分配空间的效率相当 垃圾回收器工作时,一边回收内存,一边使堆中的对 ... 如何工作

推荐整理分享常见的垃圾回收机制(常见的垃圾回收器有哪些),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:常见的垃圾回收器有那些,常见的垃圾回收器有那些,常见的垃圾回收器你知道有哪些吗,常见的垃圾回收器你知道有哪些吗,常见的垃圾回收器你知道有哪些吗,常见的垃圾回收算法不包括,常见的垃圾回收器有那些,常见的垃圾回收器,内容如对您有帮助,希望把文章链接给更多的朋友!

在某些 Java 虚拟机中,堆的实现截然不同:它更像一个传送带,每分配一个新对象,它就向前移动一格。

这意味着对象存储空间的分配速度特别快。Java 的"堆指针"只是简单地移动到尚未分配的区域,所以它的效率与 C++ 在栈上分配空间的效率相当

垃圾回收器工作时,一边回收内存,一边使堆中的对象紧凑排列,这样堆指针就可以更容易的移动到空闲区域的位置上

垃圾收集器在分配存储空间的同时会将对象重新排列,由此实现一个高速的、有无限空闲空间的堆模型。

对象可能不被垃圾回收垃圾回收不等于析构垃圾回收只与内存有关无论是“垃圾回收”还是“终结” ,都不一定保证会发生;如果java虚拟机(JVM)并未面临内存耗尽的情况,它可能不会浪费时间执行垃圾回收以恢复内存finalize()方法 (有个大概印象即可)finalize()方法

需要使用finalize()的特殊情况:你创建的对象不是通过new来分配内存的,而垃圾回收器只知道如何释放用new创建的对象内存。java允许在类中定义一个名为finalize()的方法(继承与Object)来处理这种情况

finalize()方法 的使用案例

释放 通过某种创建对象方式之外的方式 为对象分配的存储空间

解释:上边的情况 主要发生在使用本地方法的情况下,本地方法主要支持C/C++,这也许会调用C的malloc()函数来分配空间,这时,如果没用调用free()方法主动释放malloc到的空间,就会造成内存泄漏,所以需要在finalize()方法中调用free

终结条件

安全的标记对象是否可以被终结,例如下例 要销毁未被登记的Book对象时,报错

System.gc();强制终结

class Book{ boolean checkedOut = false; public Book(boolean checkOut) { this.checkedOut = checkOut; } void checkIn(){ this.checkedOut = false; } @Override protected void finalize()throws Throwable{ //只有登记过的 才能被删除 这就可以作为终结的条件 if(checkedOut){ System.out.println("ERROR: checked out"); } // Normally, you'll also do this: // super.finalize(); // Call the base-class version }}public class JavaTest{ @Test public void test8() throws InterruptedException { Book book = new Book(true); book.checkIn(); new Book(true); System.gc(); Thread.sleep(1000); }}垃圾回收机制引用计数

原理:每个对象中都有一个引用计数器,每当有引用指向该对象时,引用计数器+1;当引用离开作用域或是被置为null时,引用计数器-1;如果发现某个对象的引用计数为0时,就释放其空间(引用计数器模式经常会在计数器为0时立即释放对象)

特点:

简单

速度慢(开销不大,但在整个生命周期频繁发生的负担)

在每次内存对象被引用或引用被销毁的时候都必须修改引用计数,这类操作被称为footprint。引用计数的footprint是很高的。这使得程序整体的性能受到比较大的影响

出现循环引用时会出问题(应该被回收,但没有)

.btw:"引用计数通常用于解释垃圾收集的工作方式,但它似乎并没有出现在任何JVM实现中"

更快的策略依据

对于任何没有被废弃的对象,最终都能追溯到它存活在栈或静态存储区中的引用

因此,如果从栈和静态存储区开始遍历所有引用(包括对象内部的),就能找到所有存活的对象

匿名对象的相关思考:我们通常将匿名对象作为方法参数传递,func(new B()),在该方法中,B对象被关联了引用

常见的垃圾回收机制(常见的垃圾回收器有哪些)

所以,遍历所有的引用即可得到所有“活”的对象,然后再去遍历这些对象中的引用,如此反复,就能得到一个对象网络,其中的对象就都是 活 的;

循环引用示例class A{ public B b;}class B{ public A a;}public class Main{ public static void main(String[] args){ A a = new A();// A对象被引用 A对象计数器+1 B b = new B();// B对象被引用 B对象计数器+1 a.b=b;// B对象被引用 B对象计数器+1 b.a=a;// A对象被引用 A对象计数器+1 }}

上例 当栈上的引用遍历到a,发现a对象中有个B对象的引用,指向b,这个b引用中又有个A的引用 又指向a 如此循环 根本找不到活的对象

这样也解决了循环引用问题,循环引用的对象不会被发现

停止-复制(stop-and-copy)

原理:先暂停程序的运行,然后将所有存活的对象从当前堆复制到另一个堆,没有被复制的就是需要垃圾回收的,而且,当对象被复制到新堆后,他们紧凑排列的,一个挨着一个

特点:

解决了循环引用的问题(循环引用的对象不会被发现)非后台回收模式(需要在程序暂停的情况下进行)相对较快效率低下

得有两个堆:还得在这两个分离的堆之间来回折腾,得维护比实际多一倍的空间

某些jvm的解决方式:按需在堆中分配几块较大的内存,复制动作就发生在这大内存间

复制本身:一旦程序进入稳定状态,可能只会产生少量垃圾,甚至没有,就算是这,复制回收器也得将所有 内存从一处复制到另一处,太浪费了

某些JVM的解决方式:进行检查,要是没有新的垃圾产生,就会转换到“标记-清扫"模式(SUN公司早期JVM一直在用)。对一般用途,这种方法很慢,但当程序只会产生少量或者不产生垃圾,他速度就很快了切换到标记清扫方式清理标记-清扫

原理:标记:从栈和静态存储区出发,遍历所有引用,找出所有“活”对象,每找到一个,就给对象一个标记,直到遍历完所有对象;清扫:没有被标记的对象将被清理。

特点:

解决了循环引用的问题(循环引用的对象不会被发现)相比停止-复制 较为高效(不会有任何复制动作)非后台回收模式(需要在程序暂停的情况下进行)处理完后剩下的堆空间是不连续的垃圾回收器若希望得到连续的空间,就需要整理剩下的未被清理的对象补充:标记-整理

原理:标记:从栈和静态区域出发,遍历所有引用,对遍历过程中得到的活的对象进行标记;整理:将标记过的对象,把他们从内存开始的地方按照顺序依次摆放好,中间没有任何缝隙,在摆放完最后一个对象后,对后面的内存区域直接回收。

JVM中的块(感觉像是年龄分代)内存分配以较大的"块"为单位,较大的对象会单独占一个块。块用年代数来记录自己是否存活,若块被引用,年代数+1。垃圾回收器会对上一次回收过后 新分配的块进行整理垃圾回收器定期会清理含有小对象的那些块将被复制、整理大型对象 不会被复制(只有年代数会增加)补充:分代收集算法

摘自JavaGuide

当前虚拟机的垃圾收集都采用分代收集算法,这种算法没有什么新的思想,只是根据对象存活周期的不同将内存分为几块。一般将 java 堆分为新生代和老年代,这样我们就可以根据各个年代的特点选择合适的垃圾收集算法。

比如在新生代中,每次收集都会有大量对象死去,所以可以选择”标记-复制“算法,只需要付出少量对象的复制成本就可以完成每次垃圾收集。而老年代的对象存活几率是比较高的,而且没有额外的空间对它进行分配担保,所以我们必须选择“标记-清除”或“标记-整理”算法进行垃圾收集。

标记清扫与停止复制的切换机制(自适应)

如果对象一个个的都很稳定,此时如果垃圾回收效率降低了,就会切换到“标记-清扫”模式,以提高垃圾回收的效率,(此时jvm持续监视) 如果堆中的碎片多了,那么就赶紧切换回“停止-复制”模式,以真整理堆空间,保持堆的高速运转。

HotSpot技术java执行步骤

即时编译技术(Just-in Time JIT)

想要了解更多请移步什么是JIT?怎么优化? - 知乎 (zhihu.com)

热点代码分为两类:

多次调用的方法多次执行的循环体,实际上也会以整个方法作为编译对象

如何判断热点代码请看原文

可以把 全部或部分 程序 直接翻译为本地机器码,这就省去了JVM翻译,所以运行更快

为什么不能用这个技术 编译所有代码?

这个技术贯穿整个程序的生命周期,累加起来慢的要死会增加可执行代码的长度(字节码要比即时编译器展开后的本地机器码小很多),导致页面调度,使程序运行变慢即时编译时以方法为单位的,如果编译出来的代码运行不了几次,就白编译了惰性评估

即时编译器只有在必要时,才编译代码

这样,从未被执行的代码也许就压根不会被 JIT 编译。

新版 JDK 中的 Java HotSpot 技术就采用了类似的做法,代码每被执行一次就优化一些,所以执行的次数越多,它的速度就越快。

逃逸分析技术

请移步至深入理解Java中的逃逸分析

逃逸分析的基本行为就是分析对象动态作用域:当一个对象在方法中被定义后,它可能被外部方法所引用,例如作为调用参数传递到其他地方中,称为方法逃逸。

本文链接地址:https://www.jiuchutong.com/zhishi/310586.html 转载请保留说明!

上一篇:帝国cms常用标签总结(帝国cms插件编写教程)

下一篇:js有哪些改变自身值的方法(js改变内容)

  • 钉钉能不能同时500人直播

    钉钉能不能同时500人直播

  • 苹果锁屏的手电筒和相机怎么打开(苹果锁屏的手电筒怎么取消)

    苹果锁屏的手电筒和相机怎么打开(苹果锁屏的手电筒怎么取消)

  • opporeno4pro电池是多大mAh的(opporeno4pro的电池容量)

    opporeno4pro电池是多大mAh的(opporeno4pro的电池容量)

  • 电脑老是黑屏为什么(为啥电脑老黑屏)

    电脑老是黑屏为什么(为啥电脑老黑屏)

  • vivoy3有没有深色模式(vivoy3有深色模式吗)

    vivoy3有没有深色模式(vivoy3有深色模式吗)

  • 电脑出现americanmegatrends怎么办(电脑出现americanmegatrends怎么办图片)

    电脑出现americanmegatrends怎么办(电脑出现americanmegatrends怎么办图片)

  • d盘和e盘的区别(硬盘蓝盘和绿盘的区别)

    d盘和e盘的区别(硬盘蓝盘和绿盘的区别)

  • 腾讯共享文档如何创建共享(腾讯共享文档如何加密)

    腾讯共享文档如何创建共享(腾讯共享文档如何加密)

  • 抖音的作品为什么别人看不到(抖音的作品为什么会重合在一起)

    抖音的作品为什么别人看不到(抖音的作品为什么会重合在一起)

  • 华为荣耀8x有没有红外线功能(华为荣耀8X有没有)

    华为荣耀8x有没有红外线功能(华为荣耀8X有没有)

  • prog键是什么意思(prog啥意思)

    prog键是什么意思(prog啥意思)

  • 抖音拍视频脸大怎么调(抖音拍视频脸大怎么办)

    抖音拍视频脸大怎么调(抖音拍视频脸大怎么办)

  • 华为手机黑屏拍不了照(华为手机黑屏拍照怎么办)

    华为手机黑屏拍不了照(华为手机黑屏拍照怎么办)

  • 抖音钻卡怎么给别人(抖音钻卡怎么分红包)

    抖音钻卡怎么给别人(抖音钻卡怎么分红包)

  • 子网地址是什么(子网地址是什么网络地址还是ip地址)

    子网地址是什么(子网地址是什么网络地址还是ip地址)

  • 华为手机玩游戏掉帧怎么办(华为手机玩游戏卡顿怎么办)

    华为手机玩游戏掉帧怎么办(华为手机玩游戏卡顿怎么办)

  • 华为手机怎么下载谷歌商店(华为手机怎么下载steam)

    华为手机怎么下载谷歌商店(华为手机怎么下载steam)

  • oled烧屏能修复吗(oled烧屏)

    oled烧屏能修复吗(oled烧屏)

  • 怎么查停机的手机号码(怎么查停机的手机号欠了多少钱电信)

    怎么查停机的手机号码(怎么查停机的手机号欠了多少钱电信)

  • 户户通小锅怎么升级

    户户通小锅怎么升级

  • vuevlog如何调速度(vue vlog加速后没声音)

    vuevlog如何调速度(vue vlog加速后没声音)

  • iphone7和6s外观区别(iphone7和iphone6外观区别)

    iphone7和6s外观区别(iphone7和iphone6外观区别)

  • soul怎么跟关注的人聊天(soul怎么加关注人的房间)

    soul怎么跟关注的人聊天(soul怎么加关注人的房间)

  • 拼多多怎么凑单一起付(拼多多怎么凑单满减再退款)

    拼多多怎么凑单一起付(拼多多怎么凑单满减再退款)

  • bizimg是什么文件夹可以删除吗(bib是什么文件格式)

    bizimg是什么文件夹可以删除吗(bib是什么文件格式)

  • 苹果x有没有nfc(iphonex有nfc吗)

    苹果x有没有nfc(iphonex有nfc吗)

  • qq轻聊版如何看空间(qq轻聊版如何查看空间)

    qq轻聊版如何看空间(qq轻聊版如何查看空间)

  • 【BEV】TPVFormer复现以及原理

    【BEV】TPVFormer复现以及原理

  • 进出口环节增值税计税基础
  • 分期付款的消费税按实际收入算吗对吗
  • 残疾人个人所得税
  • 物业公司车棚算固定资产吗
  • 工会经费按什么交
  • 增值税冲红附加税费可以退吗
  • 个人独资企业有章程没有
  • 一般纳税人进项税额怎么算
  • 旧公司库存如何管理
  • 购买的固定资产没有使用,是否计提折旧
  • 购进货物既用于应税项目又用于免税项目的
  • 知识产权投资是什么意思
  • 改建的固定资产
  • 退税后钱到哪里
  • 那些发票可以报
  • 小规模红字发票怎么做账务处理
  • 发票显示不抵扣什么意思
  • 有关增值税期末留抵税额的会计分录
  • 收到银联客户备注短信
  • 企业有哪些o
  • 合理损耗如何计算单价?
  • 投标费用属于什么会计科目
  • 会议费 报销
  • 年度企业所得税申报表在哪里打印
  • 费用报销操作流程
  • linux root没有权限
  • 购买理财产品收到的利息分录
  • PHP:base64_encode()的用法_url函数
  • csinsm32.exe是安全的进程吗 csinsm32进程有哪些用处
  • mch是什么文件
  • 绩效奖个人所得怎么算
  • 坏账准备怎么做资产负债表
  • 排灯节起源
  • 电子承兑可以提前贴现吗
  • yii gridview
  • 外经证核销期限是多久
  • php的中文名
  • 金蝶怎么加人
  • 提供餐饮服务购入农产品的进项税额抵扣问题
  • 长期借款的处理原则
  • 筹办期间发生的广告费和业务宣传费可以扣除吗
  • 其他应收款如何计提减值准备
  • 单位为职工订做活动通知
  • javagui框架
  • 织梦开发教程
  • 财务报表与财务分析的关系
  • 预扣预缴和汇算清缴是什么意思
  • 母公司无偿借款给子公司
  • 制作费用和管理费用
  • 借管理费用贷应交税费个人所得税
  • 预付账款未取得发票
  • 微信转账截图可以作为会计凭证吗
  • 发票税号与公司税号不一致
  • 公司注销财务账本怎么处理
  • 购房发票丢了怎么收房
  • 一般纳税人开错税率严重吗
  • 老项目简易征收税率
  • 实现分页功能的多种原理方案
  • sql游标用法
  • mysql 5.7.28安装
  • centos怎么配置yum
  • freebsd操作命令
  • win7系统打开网络看不到其他电脑
  • centos挂载lun
  • 笔记本不支持win8
  • win8电脑怎么设置定时开机
  • Android OpenGL ES(二)----平滑着色
  • node.js的作用是什么
  • 创建nodejs项目的步骤
  • 高级控件动态数据加载过程有哪些
  • android从服务器获取数据
  • android_zh
  • 最基本的实现进程是
  • activity启动原理
  • checkbox批量删除
  • python对文件操作采用的统一
  • jQuery+Ajax+PHP弹出层异步登录效果(附源码下载)
  • 人力资源差额发票
  • 三证合一开票信息
  • 纪律作风如何形容
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设