美文网首页
[Unity] WeakReference持有Unity资源对象

[Unity] WeakReference持有Unity资源对象

作者: _Walker__ | 来源:发表于2023-12-04 12:01 被阅读0次
  • Unity2021

1、测试目的

我们希望优化AB包资源缓存策略,要求有两点:

  1. 可以在C#测持有资源的引用,不必每次使用时都去AB包里Load
    曾经做过一个简单的测试,从Dictionary缓存里取资源,比每次Load效率高几十倍(排除首次加载)
  2. 从AB包里加载出来的资源,可以被UnloadUnused接口卸载掉
    因为某些AB包的粒度较粗,所有资源都要跟着AB包一起卸载,对内存浪费还是很大的。希望资源的卸载周期跟AB包的卸载周期分离。

2、测试结论

WeakReference wr = new WeakReference(texture);
WeakReference<Texture> wr2 = new WeakReference<Texture>(texture);

2.1 对象创建的后的默认状态

  • 被WeakReference持有的对象,很长时间不会被回收。
    具体的极限时间没测试,这里的“长”是相对于后面的“短”来说的。
    注意:这里说的是C#对象(Texture这个类的对象),不是Unity的资源(Native侧的图片二进制数据)

2.2 执行UnloadUnused之后

  • 被Weak持有的Unity资源会立刻从内存卸载掉
  • 短时间内,wr.IsAlive是true,当访问了wr.Target后(打Log、取字段)都会将资源加载进内存!!
  • 长时间后,wr.IsAlivefalse同时wr.Target是Null,这里说明C#的对象被回收了。这时候再访问wr.Target也不会将资源加载进内存
  • 下面这套操作,C#对象被回收,Unity资源留在内存:
    1. 执行UnloadUnusedAssets:此时资源从内存卸载
    2. 立刻访问wr.Target:资源被加载回内存
    3. 经过长时间等待(Editor里大概几十秒):C#对象被回收,Unity资源留在内存无法被访问(可以被UnloadUnused等卸载)

2.3 执行Unload(true)之后

  • Unity资源立刻从内存卸载
  • 短时间内,wr.IsAlive是true,wr.Target是null,访问wr.Target也无法将资源加载进内存
  • 长时间后,wr.IsAlive是false,wr.Target是Null

特别说明:上面描述wr.Target时用了【null】跟【Null】两个写法,这里时有意为之,它们都是Console打印的内容,代表了Unity对象的不同状态:

  1. Null:代表这个变量指向的对象是null,也就是没有对象
  2. null:代表这个变量指向的对象是有值的(如:一个Texture),但是这个对象处于一个被销毁、不可用的状态,Unity将这种状态状态的对象的name改为了"null",同时ToString也是"null"

相关文章

网友评论

      本文标题:[Unity] WeakReference持有Unity资源对象

      本文链接:https://www.haomeiwen.com/subject/znsbydtx.html