Coder Social home page Coder Social logo

Comments (9)

xubaiself avatar xubaiself commented on August 14, 2024 2

哦哦,我懂了,非常感谢您的回答。

关于资源管理我还有一个问题,包括我自己之前在尝试写资源管理的时候也在思考这个问题,就是说从一个AssetBundle中加载的资源,如果不卸载Assetbundle那么该资源就没法被卸载是么?

因为往往是,当所有从AssetBundle中加载的资源的引用为0时AssetBundle的引用为0然后可以卸载AssetBundle。但是比如说a1和a2。从一个AssetBundle中加载,我现在不用a1了,但是a2一直被使用,那是不是a1没办法被单独卸载呢?AssetBundle似乎也没有提供卸载资源的API,只有加载资源和卸载AssetBundle的api。那这样我的理解就是a1没用了,但一直在内存中没法卸载,因为a2还依赖着这个AssetBundle。这样是不是就导致内存的被无效资源占用呢?这个问题应该在划分AssetBundle的时候解决么?

有这个问题主要是因为Resources那套api提供了load和unload资源的方法,而AssetBundle这边似乎只有load资源而不能单独unload资源。

from yooasset.

MOMOLAXI avatar MOMOLAXI commented on August 14, 2024 1

可以参考YoAssets里面的OperationSystem, 他就是你所描述的, 将操作分配在每一个update中, 而且可以设置每一个AsyncOperationBase的执行时间再MaxSliceTime之间,除非那一帧的某一个操作太耗时。
所以说,有一系列各种资源加载、文件验证等等AsyncOperationBase的子类,都在OperationSystem里面被Update,保证每个操作在固定间隔时间内update。
至于你说的资源卸载问题,可以看到里面有继承IDispose接口的operation

  1. 当你的资源被引用的时候,这个operation虽然没有被代码引用了,但是里面的成员变量(UnityEngine.Object)还在被你代码里某些地方引用着,所以这个operation类还在内存里。
  2. 当这个资源引用的地方没有了(GameObject被destroy或者其他情况), 这个operation类就会进入被GC状态,这个时候就会调用这个operation的IDispose接口的方法,这个方法里减少该资源的引用计数。
  3. 在持有AssetBundle的BundleProvider里会在每帧update中去检测这个计数,计数到0了就会调用AssetBundle.Unload(true)去卸载资源了。
  4. 总结来说就是通过C#类自动进入GC状态去触发IDispose去自动减少引用计数来进行卸载ab包,相当于把资源减少引用计数的操作托管给了C#(CLR虚拟机), 这样一来就省去手动调用卸载的风险,减少一些心智负担,方便了很多。

from yooasset.

gmhevinci avatar gmhevinci commented on August 14, 2024

资源加载并不会太耗时,耗时大部分是花在了实例化上,所以针对这个问题,operation system代码里,采取了分帧处理逻辑来避免卡顿。

from yooasset.

gmhevinci avatar gmhevinci commented on August 14, 2024

unity的协程本质上也是在主线程里处理的,在mono内部update方法里按照顺序执行所有协程,你是干预不了的。

from yooasset.

gmhevinci avatar gmhevinci commented on August 14, 2024

AssetBundle加载出来的资源对象,单独卸载也可以。但是对一个稳定的资源系统框架来讲,这是错误的行为,他会造成依赖链的不稳定,最主要原因就是GameObject对象无法卸载。

from yooasset.

gmhevinci avatar gmhevinci commented on August 14, 2024

之前考虑过通过监测UnityEngine.Object是否销毁来做自动释放。后来发现问题太多就放弃了。

  1. 当这个资源引用的地方没有了(GameObject被destroy或者其他情况), 这个operation类就会进入被GC状态,这个时候就会调用这个operation的IDispose接口的方法,这个方法里减少该资源的引用计数。

这个需要OP常驻,然后每帧去检测Obj是否销毁。而且在OP创建完成之后,Obj可能还未加载完成,或加载失败。

from yooasset.

MOMOLAXI avatar MOMOLAXI commented on August 14, 2024

之前考虑过通过监测UnityEngine.Object是否销毁来做自动释放。后来发现问题太多就放弃了。

  1. 当这个资源引用的地方没有了(GameObject被destroy或者其他情况), 这个operation类就会进入被GC状态,这个时候就会调用这个operation的IDispose接口的方法,这个方法里减少该资源的引用计数。

这个需要OP常驻,然后每帧去检测Obj是否销毁。而且在OP创建完成之后,Obj可能还未加载完成,或加载失败。

确实是的,我之前也尝试过使用mono组件把引用计数通知回来,但是异常情况太多了。另一个情况又是new的对象不管了,看着非常刺眼,所以目前策略就是够用, 问题不大就行了。

from yooasset.

pengjugame avatar pengjugame commented on August 14, 2024

我这里有一个经验方法不知道合适不合适,方法如下:
yoo已经设置的非常简单明了,对资源管理再上层封装一个context,通过context管理 “游戏逻辑上”的资源加载。
(1)对大一些的资源需求来说,比如战斗,我createContext(battle)生成一个battle的资源管理,里面专门处理战斗相关资源,在战斗中的资源加载通过battle-context.load去加载,战斗完成后,我直接在context卸载的时候,将整个战斗的资源句柄通通卸载。
(2)对一些小的资源需求来说,比如某个活动功能,我可以根据tag去管理,整体活动是一个context,我可以context.loadByTag("xxxtag")去加载和卸载当前tag的,在当前活动页面关闭后,我再conetxt.destroy("xxxtag")
(3)默认的继承IDispose的句柄是最后的保证,保证我们有GC的时候,卸载了相应的资源

想当于
第1层:手动Destroy相关Instance,并把能清除的引用尽量清
第2层:从Context的区域删除当前功能的引用资源Handle
第3层:当整体大功能关闭时,直接ReleaseContext,并删除所有资源Handle
第4层:如果删不尽的,Yoo里面做IDispose的保护,保证它最后肯定是卸载掉的

不知道这种想法怎么样,目前我正在新项目使用Yoo,也希望对我的这种方法给一定的评判,谢谢啦

from yooasset.

gmhevinci avatar gmhevinci commented on August 14, 2024

不错的经验之谈。这个有点对象池的意思。

from yooasset.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.