关于GC

本文深入探讨Java虚拟机的垃圾回收机制,介绍如何通过根搜索算法识别不再使用的对象,并详细解释对象可达性分析的过程及四种不同类型的引用。同时,文章还讨论了对象如何通过finalize()方法自救的机制。

《深入理解Java虚拟机》真的是看多少遍都不多,每次都有新体会
堆中存放着许多对象实例,许多是已经不用的(或者称死亡的),不清理它太占内存,垃圾回收器就是回收这些对象,释放对象所占的内存。

怎么判断对象已死呢?
2种方法:
1,引用计数法:(解决不了相互引用的问题,已经咋不用了)
2,根搜索算法
堆内存就像一颗大树,树根叫GC root,根搜索算法就是,以树根为起点开始搜索,搜索走过的路径叫引用链(相当于树枝),当一个对象没有被任何引用链相连,属于树外的东西,这个对象是不可达的;
树根是什么东西呢?
虚拟机栈引用的对象
方法区中类静态属性引用的对象
方法区中常量引用的对象
本地方法栈中JNI引用的对象
再说说引用(4类):
强引用:只要引用还在,无论如何不会被回收的引用
软引用:当内存不够时会被考虑回收
弱引用:只能存活到下次回收之前
虚引用:如同虚设,目的只是希望,在回收的时候,给系统一个通知

接下来开始回收:
找到了不可达对象后
1.筛选:筛选条件是,对象是否覆盖finalize()方法,并且之前没有被调用过,将筛选出来的对象放到F-Queue队列里,并稍后由虚拟机自动建立的一个低优先级的线程执行,
2.标记:若将死对象在finalize()方法中,将自己与引用链上的任何一个对象建立了关联,成功解救了自己,将它标记并移出这个将死集合
重点!对象只可能逃脱一次,当第二次发现它是个不可达对象的时候,以为他的finalize()方法已经被执行过一次了,finalize()方法不会再被执行!

自己的理解,有不对的欢迎指出!一起进步~

在 Unreal Engine 中,垃圾回收(GC)机制负责自动管理 UObject 的生命周期。然而,在某些情况下,需要采取特定措施来防止 UObject 被过早回收。以下是相关机制和方法: UObject 通常通过引用计数机制来决定是否被回收。如果一个 UObject 没有任何强引用指向它,那么在下一次垃圾回收时,该对象将被标记为可回收,并最终被释放[^2]。为了确保 UObject 不被回收,可以使用以下几种方式: ### 1. 使用 `AddToRoot()` 和 `RemoveFromRoot()` 如果一个 UObject 是通过普通 C++ 类中的指针访问的,而不是通过 UPROPERTY,那么它不会被引擎自动追踪。在这种情况下,可以通过调用 `AddToRoot()` 来显式地将其标记为根对象,从而避免其被回收。当不再需要保留该对象时,应调用 `RemoveFromRoot()` 来允许 GC 正常回收它[^3]。 ```cpp UMyObject* m_Object = NewObject<UMyObject>(); m_Object->AddToRoot(); // 在析构函数中 m_Object->RemoveFromRoot(); ``` ### 2. 使用 UPROPERTY 宏 如果 UObject 是作为另一个 UObject 或 AActor 的成员变量存在,并且使用了 `UPROPERTY()` 宏进行声明,则引擎会自动维护对该对象的引用,从而阻止其被 GC 回收,直到拥有它的对象也被回收为止[^2]。 ```cpp UPROPERTY() TObjectPtr<UMyWidget> MyWidget; ``` ### 3. 避免悬空引用 在移除 UObject 的引用时,例如从视口中移除一个 Widget,必须手动将其指针置为 `nullptr`,以确保 GC 可以识别其不再被使用。否则,即使对象已经被销毁,仍然存在的非空指针可能导致访问非法内存地址的问题[^2]。 ```cpp MyWidget->RemoveFromParent(); MyWidget = nullptr; // 允许 GC 回收 ``` ### 4. 控制 GC 行为 UE4 提供了控制 GC 的接口,如 `CollectGarbage()` 函数,它可以在特定时刻强制执行垃圾回收。该函数接受参数来决定哪些对象应该保留,并通过锁机制确保 GC 过程中不会有其他线程修改 UObject 状态[^1]。 ```cpp CollectGarbage(RF_Keep, false); ``` ### 5. 调整 GC 参数 在某些情况下,可以通过调整 GC 的配置参数来影响其行为。例如,增加 `gc.MaxAttemptsPerFrame` 可以减少强制 GC 的频率,从而降低异步加载与 GC 并发的风险[^4]。 ```ini [/Script/Engine.GarbageCollectionSettings] gc.MaxAttemptsPerFrame=1000 ``` ### 加载后 UObject 是否存在 UObject 在加载后是否仍然存在取决于是否有对其的有效引用。只要存在至少一个强引用(如 UPROPERTY、根对象引用等),该 UObject 就不会被 GC 回收。只有当所有引用都被清除或置空后,UObject 才可能在下一次 GC 周期中被回收[^2]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值