博客
关于我
【转载】Java 对象之死
阅读量:289 次
发布时间:2019-03-01

本文共 1296 字,大约阅读时间需要 4 分钟。

Java垃圾回收机制是Java虚拟机(JVM)中保证内存管理的重要部分。它的核心目标是识别那些不再被使用的对象,并回收它们占用的内存空间。这种机制对保持应用程序的高效运行至关重要。

如何判断对象“无用”?

在JVM中,判断对象是否无用主要通过两种算法:引用计数和根集算法。

引用计数算法

引用计数算法通过为每个对象维护一个引用计数来实现。当引用计数为零时,说明该对象没有被其他对象引用,成为JVM回收的目标。这种算法简单高效,但存在一个明显的缺陷:当对象之间形成闭环引用时,无法通过引用计数判断对象是否无用。例如,对象A引用对象B,对象B再引用对象A,这种情况下引用计数都不会降到零,导致这些对象无法被回收。

根集算法

为了解决引用计数算法的局限性,现代JVM主要采用根集算法。根集算法从GCRoot(如静态变量)开始遍历所有引用关系,找出所有可以被其他对象“到达”的对象。如果某个对象无法被其他对象到达,则它被判定为“无用”,即可被回收。这种算法能够有效处理闭环引用问题,是当前JVM的主要垃圾回收算法。

对象回收之后的内存如何处置?

在垃圾回收完成后,JVM需要对释放的内存进行合理分配。具体的回收算法主要有标记-清除、标记-复制和标记-整理三种。

标记-清除

标记-清除算法的核心步骤是标记所有无用对象,然后清除它们占用的内存。标记过程需要遍历所有对象,找出那些引用计数为零或无法被根集算法遍历到的对象。清除过程则负责将这些标记对象的内存空间重置为零,以供新对象使用。

这种算法简单直接,但存在内存碎片化的问题。由于标记和清除都需要遍历内存空间,效率较低,且难以处理大对象分配。

标记-复制

标记-复制算法通过在内存中划分预留区域来优化垃圾回收过程。在标记阶段,与标记-清除相同;在复制阶段,JVM将正在使用的对象复制到预留区域,之后清除所有不在预留区域内的内存。这种方法有效减少了内存碎片,但需要牺牲一半的内存资源,显然在大多数情况下难以接受。

标记-整理

标记-整理算法结合了标记-清除和标记-复制的优点。标记过程不变,但清除阶段将所有正在使用的对象(标记对象)向内存末端移动,占据一块连续的区域。随后清除所有不在预留区域内的内存。这种方法解决了内存碎片问题,同时也显著降低了垃圾回收的内存占用。

分代混合算法

在现代JVM(如HotSpot TM)中,分代混合算法是主要的垃圾回收策略。该算法将对象按照其生命周期范围划分为新生代和老生代两个区域。新生代对象通常较短生命周期,垃圾回收时采用标记-复制算法;老生代对象生命周期较长,垃圾回收时采用标记-清除或标记-整理算法。

Stop the world

在垃圾回收过程中,JVM需要暂停所有Java线程(Stop the world),以确保GC操作的正确性。这是因为引用关系的快照是基于某一时刻的状态,随时间推移可能发生变化。JVM通过OopMap数据结构记录引用关系,确保垃圾回收过程的准确性。

频繁的Stop the world操作会对应用程序性能产生显著影响。如何在内存使用和性能之间找到平衡点,是开发者需要重点关注的问题。

转载地址:http://bcqx.baihongyu.com/

你可能感兴趣的文章
php筛选js,php如何多条件筛选js代码
查看>>
R730服务器做了raid的硬盘,插在R720上面可以用吗?
查看>>
PHP类数组式访问(ArrayAccess接口)
查看>>
PHP系列:浅谈PHP中isset()和empty() 函数的区别
查看>>
PHP索引数组unset的坑-array_values解决方案
查看>>
PHP索引数组排序方法整理(冒泡、选择、插入、快速)
查看>>
PHP线程安全和非线程安全
查看>>
R3LIVE开源项目常见问题解决方案
查看>>
php缃戠珯,www.wfzwz.com
查看>>
php缓存查询函数
查看>>
php编写TCP服务端和客户端程序
查看>>
php编码规范
查看>>
PHP编码规范-PSR1、psr2 /psr3 psr4
查看>>
PHP编程效率的20个要点
查看>>
PHP网页缓存技术优点及代码
查看>>
PHP自动化测试(一)make test 和 phpt
查看>>
php自定义函数: 文件大小转换成智能形式
查看>>
php英语单词,php常用英语单词,快速学习php编程英语(6)
查看>>
R3.4.0安装包时报错“需要TRUE/FALSE值的地方不可以用缺少值”,需升级到R3.5.0
查看>>
PHP获取curl传输进度
查看>>