gpt4 book ai didi

unity3d - Unity WebGL Assets 包内存未释放

转载 作者:行者123 更新时间:2023-12-04 01:36:07 28 4
gpt4 key购买 nike

我正在加载和缓存 Assets 包 统一使用以下函数 webgl :

 IEnumerator DownloadAndCacheAB(string assetName)
{
// Wait for the Caching system to be ready
while (!Caching.ready)
yield return null;

// Load the AssetBundle file from Cache if it exists with the same version or download and store it in the cache
using (WWW www = WWW.LoadFromCacheOrDownload(finalUrl, 1))
{

yield return www;

if (www.error != null)
{
Debug.Log("WWW download had an error:" + www.error);
}

AssetBundle bundle = www.assetBundle;

if (assetName == "")
{
GameObject abObject = (GameObject)Instantiate(bundle.mainAsset, gameObject.transform.position, gameObject.transform.rotation);
abObject.transform.parent = this.transform;
SetTreeShaderSettings(abObject);
}
else
{
GameObject abObject = (GameObject)Instantiate(bundle.LoadAsset(assetName), gameObject.transform.position, gameObject.transform.rotation);
abObject.transform.parent = this.transform;

}

// Unload the AssetBundles compressed contents to conserve memory
bundle.Unload(false);

} // memory is freed from the web stream (www.Dispose() gets called implicitly)
}
每当我想删除对象时,我都会使用此功能。
 public void RemoveBundleObject()
{
//if (www != null)
//{
// www.Dispose();
// www = null;
if (loadBundleRef != null)
{
StopCoroutine(loadBundleRef);
}
if (this.gameObject.transform.childCount > 0)
{
Destroy(this.gameObject.transform.GetChild(0).gameObject);
System.GC.Collect();
}
//}
}
如您所见,我正在删除第一个 child (我从 Assets 包中获得)然后调用 GC Collect 来强制垃圾收集器。但问题是每当我卸载/销毁对象时我的内存都没有释放。现在你会想我是如何测量内存的?我正在使用来自 here 的 WebGLMemoryStats .
在 Assets 捆绑加载的几次迭代之后,我得到了这个。
enter image description here
编辑:
我现在正在使用 WebRequest 类下载 Assets 包 ( find here),但仍然无法释放内存,有时会出现 aw snap 错误。
即使我试图一次又一次地加载一个空的 webgl 构建,它也会增加内存堆,然后有时我会收到 aw snap 或内存错误和 chrome 崩溃。
enter image description here
如您所见,初始负载约为 1.2 Mb,但当我刷新页面并拍摄快照时,快照会带来内存增加。

最佳答案

请注意,您永远不会像您想象的那样完美地运行它。有一些用于清理垃圾和卸载 Assets 的实用程序,但即使您遵循所有最佳实践,您仍然可能无法让 Unity 清理所有垃圾(它在后台做了很多工作,会保留分配的内存,而您却没有多少可以做的)。如果您对这是为什么感到好奇,我建议他们在 Heap Fragmentation 上撰写文章。以及他们的Memory Optimization Guide .

就您对特定项目所做的事情而言,您至少可以进行一些改进:

1) 避免使用 WWW不惜一切代价上课。它产生的垃圾多于它的值(value),并不总是能很好地清理,并且在最新版本的 Unity 中已过时。使用UnityWebRequest改为下载捆绑包。

2) 不要养成加载捆绑包只是为了加载单个 Assets 然后卸载该捆绑包的习惯。如果您在运行时发生大量负载,这将导致抖动,并且是管理捆绑包的一种相当低效的方式。我注意到你调用 bundle.Unload(false)这意味着正在卸载捆绑包,但未加载加载的预制 Assets 。我建议以一种你可以的方式重组它:

  • 加载你需要的包
  • 从该捆绑包中加载您需要的 Assets
  • 等待所有这些 Assets 的生命周期结束
  • 调用bundle.Unload(true)

  • 3) 调用 StopCoroutine(loadBundleRef); 时要小心(如果 loadBundleRef 是一个 Coroutine 对象,它正在运行您的 Web 请求和包加载逻辑)。中断这些异步操作可能会导致内存问题。你应该有一些东西来确保 web 请求和包加载完全完成,或者在失败时抛出并让你的游戏恢复。不允许 StopCoroutine 之类的内容打断他们。

    4) System.GC.Collect();速度很慢,垃圾收集无论如何都会定期发生。谨慎使用它,您可能还想调用 Resources.UnloadUnusedAssets 在调用它之前。

    关于unity3d - Unity WebGL Assets 包内存未释放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55102548/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com