IL2Cpp深坑之WeakReference

来源:互联网 发布:大数据量 数据库 编辑:程序博客网 时间:2024/04/28 14:59

年前用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#原生语法特性时也要考虑多线程带来的问题。

1 0
原创粉丝点击