IL2Cpp深坑之WeakReference

在Unity中,使用WeakReference优化Object Cache时,发现在Android Mono环境下正常,但iOS IL2Cpp打包后,即使WeakReference.IsAlive为true,目标对象也可能已被回收。这引发对IL2Cpp中WeakReference行为的质疑,因为其IsAlive属性可能不准确。文章讨论了此问题,并提醒开发者在使用C#特性时需考虑多线程和潜在的GC风险。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

年前用WeakReference优化了下Object Cache,Object缓存时如果显式指定缓存则将其加入到强引用容器中,否则加入到WeakReference容器中,这样等GC的时候可以清除掉不再使用的Object,安卓Mono下用了好长时间没有发现问题。今天用IL2Cpp打包iOS却发现weakReference.IsAlive即使为true也会出现target被回收的情况,猜测IsAlive在Mono上有问题,后来Google一下,发现十年来大家都在吐槽WeakReference的IsAlive属性:

Don‘t trust weakreference isalive if it returns true

The WeakReference.IsAlive method can tell you if a particular object is still alive, i.e. it has not yet been garbage collected.  However, when IsAlive returns true, you can’t then necessarily interact with the object through its weak reference, because it could be garbage collected before you get a chance to use it.

For example:

WeakReference dogRef = new WeakReference(dog);
 
// Later, try to ref original Dog
 
if (dogRef.IsAlive)
{
    // Oops - garbage collection on original Dog could occur here
    ((Dog)dogRef.Target).Bark();
}
You  can  trust  IsAlive  when it returns  false , since a garbage collected object is not in danger of being reconstituted.  But the correct pattern for checking to see if an object is still alive is:

WeakReference dogRef = new WeakReference(dog);
 
// Later, try to ref original Dog
 
Dog origDog = (Dog)dogRef.Target;
if (origDog != null)
{
    origDog.Bark();
}

很明显,IL2Cpp编译后开启了多线程,判定IsAlive之后如果触发GC,Target就会被回收掉造成NullReferenceException。。。

希望il2cpp团队能够改进这一bug,今后要使用一些其他C#原生语法特性时也要考虑多线程带来的问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值