垃圾如何进行自救

垃圾如何进行自救

背景故事

在Java中,Object是所有类的祖先

img/1.png

Object类中有一个留给子类实现的方法finalize(),它的作用就是在一个对象被当做垃圾进行回收时留给它的最后自救机会

垃圾的发现

JVM的内存管理机制将原本需要程序员自己手动释放的内存可以自动去清理释放,这种方式虽然方便不少,但因为是自动去识别,肯定不如手动释放精准,所以各式各样的垃圾判断方式出现了。

引用计数法

引用计数法的关键在于给每一个实例增加一个被引用次数值,当A中有调用B时,B的引用次数会加一,引用失效时减一,当引用次数为0时,就表示这个实例需要被回收了。

这种算法实现很简单,虽然保存每个对象计数值需要额外的空间,但它还有一个致命问题,就是无法解决循环引用问题。

当两个对象实例互相引用时,该方法就会陷入死循环。

可达性分析法

很多语言的垃圾收集算法都是使用可达性分析。

通过从一个GC Root(通常是方法区中静态变量所引用的对象,虚拟机栈中引用的对象,已经启动且未停止的线程,JNI handles)的对象节点开始,向下搜索它所引用的对象实例,当一个对象可以被搜索到,就说明它是可达的,不需要回收。

当一个对象无法与GC Root连接到一起时,就是需要回收的对象。

在可达性分析的过程中,如果程序还在运行,就有可能会使一个被标记为垃圾的对象重新被引用,所以在这个过程中,会触发STW(Stop the world),应用程序会被停止下来,让垃圾收集器掌握主动权。

Stop The World

STW是根据安全点来实现的, 安全点是确保在垃圾收集前确保线程执行到安全的位置。安全点的选择通常是当前代码段不会发生引用的改变。

生存还是死亡

就算一个对象在可达性分析时被标注为垃圾,但也不是会被立即消除,而是进入一个缓刑状态,等到下一次GC之前,若无人保释,便执行清理工作。

也就是说一个垃圾从标记到回收至少要经历两次GC,第一次是判断释放是垃圾对象,然后垃圾回收器会判断垃圾对象是否有复写finalize()方法,或者说之前是否已经执行过finalize()方法,finalize就是垃圾对象的最后一次自救的机会,符合条件的垃圾对象的finalize()会被加入一个低优先级的线程队列F-Queue,

虽然说垃圾通过finalize来拯救自己听上去是很自强不息的一件事,但是垃圾回收本来就因为STW让我们本来的进程发生停顿,如果垃圾对象里面还有一些复杂的finalize自救,那么一堆对象累计下来,STW的过程就会长到无法想象。

System类中提供了一个runFinalizeion()方法让JVM去积极执行finalize来进行对象销毁,但是这是不可控的,说不定因为finalize就会导致垃圾变慢,还有一堆无法收集的对象,导致我们的程序OOM。

2

这是java.lang.ref中Finalizer的源代码,可以看到其中定义了一个Queue,还有一些add和remove,感兴趣可以自己去看看。

3

在runFinalizer中就是调用垃圾对象finalize()方法的过程了,可以看到catch中,对于执行失败的finalize方法其实是直接忽略的,也就是说就算我们想让这个对象活下去,在特殊异常情况下,这个对象也会死,而且死的不明白的,虚拟机并不会告诉我们任何信息。

所以为了性能着想,最好不要覆写对象的finalize方法,如果对象在回收时有什么操作需要执行,可以使用Cleaner来定制我们自己的处理方式,在独立的线程中处理,而不是在STW中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值