Muh*_*han 8 garbage-collection unity-game-engine assetbundle unity-webgl
我正在统一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)
}
Run Code Online (Sandbox Code Playgroud)
每当我想删除对象时,我都会使用此功能。
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();
}
//}
}
Run Code Online (Sandbox Code Playgroud)
如您所见,我正在删除第一个孩子(我是从资产捆绑包中获得的),然后调用GC Collect强制执行垃圾收集器。但是问题是,每次卸载/销毁对象时,内存都不会释放。现在您会认为我如何测量内存?我从这里使用WebGLMemoryStats 。我在资产捆绑负载几次迭代后得到了这个。
编辑: 我现在正在使用WebRequest类下载assetbundle(在此处找到),但仍然无法释放内存,有时会出现aw snap错误。
即使当我试图一次加载一个空的webgl构建时,它又一次增加了内存堆,然后有时我会遇到aw snap或内存错误以及chrome崩溃。
如您所见,初始负载约为1.2 Mb,但是当我刷新页面并进行快照时,快照带来了增加的内存。
请也考虑@Foggzie 答案以获得一些最佳实践(我使用了其中一些)!
我的代码或测试程序有两个问题。
Unity内置的WWW.LoadFromCacheOrDownload是垃圾!严重地!为什么 ?Ben Vinson和unity在他们的博客中也解释道:
内存相关问题的另一个来源是 Unity 使用的 IndexedDB 文件系统。每当您缓存资产包或使用任何与文件系统相关的方法时,它们都会存储在 IndexedDB 支持的虚拟文件系统中。
您可能没有意识到,一旦您的 Unity 应用程序启动,该虚拟文件系统就会加载到内存中并保留在内存中。这意味着,如果您对资源包使用默认的 Unity 缓存机制,则您会将所有这些资源包的大小添加到游戏的内存要求中,即使它们没有被加载。
而Unity在他的博客中明确提到使用UnityWebRequest而不是LoadFromCacheOrDownload:
最小化资源包缓存内存开销的长期解决方案是使用 WWW 构造函数而不是 LoadFromCacheOrDownload(),或者如果您使用新的 UnityWebRequest API,则使用不带哈希/版本参数的 UnityWebRequest.GetAssetBundle()。
然后在 XMLHttpRequest 级别使用替代缓存机制,将下载的文件直接存储到 indexedDB 中,绕过内存文件系统。这正是我们最近开发的,并且可以在资产商店中找到。请随意在您的项目中使用它,并根据需要进行自定义。
页面重新加载问题的内存增量似乎与 FireFox 内部机制有关。但它发生在 Chrome 中,因为当我检查内存时开发工具是打开的。
当我在 Chrome 中测量选项卡内存时,开发工具就打开了,因此它会随着每次页面刷新而增加内存。这个原因由一位Unity官方在论坛上定义
需要注意的一点是,在 Firefox 中分析页面重新加载时的内存使用情况时,请确保关闭 Firefox Web 控制台(和调试器)窗口。Firefox 有一个行为,如果 Web 控制台打开,它会使 Firefox JS 调试器保持活动状态,将所有访问过的页面固定在内存中缓存,从不回收它们。关闭 Firefox 网页控制台可以释放内存中的旧页面。
我不知道 Chrome 是否可能有类似的行为,但为了更好的措施,最好关闭其 Web 控制台以确保它不会使页面保持活动状态。
如果有人有可以发布的公开测试用例,这将有助于查明来源。
但实际上我的测试表明这个问题在 fireFox 中仍然存在,而在 Google Chrome 中解决了。
请记住,我经过长期斗争才得到这个答案。
更新:我发现当您在 Firefox 中重新加载页面时,它会获得双倍的页面内存。所以这是firefox问题,与unity webgl无关。
| 归档时间: |
|
| 查看次数: |
572 次 |
| 最近记录: |