Unity WebGL资产捆绑包内存未释放 [英] Unity WebGL asset bundle memory is not releasing

查看:645
本文介绍了Unity WebGL资产捆绑包内存未释放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用以下功能统一加载和缓存资产捆绑包: webgl :

I am loading and Caching Asset Bundles using below function in unity 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)
    }

每当我要删除对象时,我都会使用此功能.

And whenever I want to remove the object i use this function.

 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();
        }
        //}
    }

如您所见,我正在删除第一个孩子(我是从资产捆绑包中获得的),然后调用GC Collect强制执行垃圾收集器.但问题是,每当我卸载/销毁对象时,内存都不会释放.现在您会认为我如何测量内存?我正在从此处使用WebGLMemoryStats. 在资产捆绑负载反复迭代之后,我得到了这个.

As you can see I am deleting the first child (which I got from asset bundle) then call GC Collect to force garbage collector. but the problem is that my memory is not releasing whenever i unload/destroy the object. Now you will thinking that how i am measuring the memory? I am using WebGLMemoryStats from here. And i am getting this after several iteration of assetbundle load.

修改: 我现在正在使用WebRequest类下载资产捆绑包(在此处找到),但仍然无法释放内存,有时会出现aw snap错误.

I am using now WebRequest Class to download assetbundle (find here) but still unable to release the memory and sometime get aw snap error.

即使我试图一次加载一个空的webgl构建,一次又一次地增加内存堆,然后有时我会遇到aw snap或内存错误和chrome崩溃.

Even when I am trying to load an empty webgl build again and again its increase the memory heap and then sometime i get aw snap or memory error and chrome crash.

如您所见,初始负载约为1.2 Mb,但是当我刷新页面并拍摄快照时,快照带来了增加的内存.

As you can see the initial load is about 1.2 Mb but when i refresh page and take snap shot, it snapshot brings with incremented memory.

推荐答案

请同时考虑@Foggzie答案,以获取一些最佳实践(我使用了其中一些)!

我的代码或测试过程存在两个问题.

There was two issue with my code or testing procedeure.

Unity内置WWW.LoadFromCacheOrDownload很烂!严重地!为什么 ? 本·文森

Unity Built-in WWW.LoadFromCacheOrDownload is crap! Seriously! Why ? Ben Vinson and unity also explain in their blogs:

与内存相关的问题的另一个来源是IndexedDB文件系统 由Unity使用.每当您缓存资产捆绑包或使用任何 与文件系统相关的方法,它们存储在虚拟文件系统中 由IndexedDB支持.

Another source of memory-related problems is the IndexedDB filesystem used by Unity. Any time you cache an asset bundle or use any filesystem-related methods, they are stored in a virtual filesystem backed by IndexedDB.

您可能没有意识到的是此虚拟文件系统已加载 Unity应用程序启动后立即进入并保留在内存中. 这意味着如果您使用默认的Unity缓存机制 对于资产捆绑包,您要将所有捆绑包的大小添加到 游戏的内存需求,即使不是 已加载.

What you might not realize is that this virtual filesystem is loaded into and persisted in memory as soon as your Unity application starts. This means that if you are using the default Unity caching mechanism for Asset Bundles, you are adding the size of all of those bundles to the memory requirements for your game, even if they are not being loaded.

他的博客使用UnityWebRequest代替LoadFromCacheOrDownload:

And Unity Clearly mentioned in his blog to use UnityWebRequest instead LoadFromCacheOrDownload:

如果要使用新的UnityWebRequest API,则可以使用WWW构造函数代替LoadFromCacheOrDownload()或使用不带哈希/版本参数的UnityWebRequest.GetAssetBundle()(不带散列/版本参数)来最大限度地减少资产束缓存的内存开销.

A longer term solution to minimize asset bundle caching memory overhead is to use WWW Constructor instead of LoadFromCacheOrDownload() or use UnityWebRequest.GetAssetBundle() with no hash/version parameter if you are using the new UnityWebRequest API.

然后在XMLHttpRequest级别使用替代的缓存机制, 将下载的文件直接存储到indexedDB中,绕过了 内存文件系统.这正是我们最近开发的 它在资产商店中可用.随时在您的计算机中使用它 项目并根据需要对其进行自定义.

Then use an alternative caching mechanism at the XMLHttpRequest-level, that stores the downloaded file directly into indexedDB, bypassing the memory file system. This is exactly what we have developed recently and it is available on the asset store. Feel free to use it in your projects and customize it if you need to.

2.打开Chrome开发工具时不要测量内存

页面重新加载上的内存增加问题似乎与FireFox内部机制有关.但是由于我在检查内存时打开了dev工具,因此它在chrome中发生.

2. Don't Measure Memory when Chrome Dev Tools are Open

The memory increment on page reload problem seems related to FireFox internal mechanism. But It was occurring in chrome due to the dev tools which were open when I was checking the memory.

一旦我在chrome中测量了我的选项卡内存,开发工具就会打开,因此每次刷新页面时它都会增加内存.此原因由中的一个定义论坛上的Unity官员

Once I was measuring my tab memory in chrome the dev tools was open so it increment the memory with each page refresh. This reason defined by one of the Unity official at forum

需要注意的一点是,在分析页面上的内存使用情况时会重新加载 在Firefox中,请确保具有Firefox Web控制台(和调试器) 窗户关闭了. Firefox的行为是,如果打开了Web控制台,它将 使Firefox JS调试器保持活动状态,该调试器会将所有访问的页面固定到 被缓存在内存中,永不回收它们.关闭Firefox网站 页面控制台允许从内存中释放旧页面.

One point to note is that when profiling memory usage on page reloads in Firefox, make sure to have the Firefox web console (and debugger) window closed. Firefox has a behavior that if web console is open, it keeps the Firefox JS debugger alive, which pins all visited pages to be cached in memory, never reclaiming them. Closing the Firefox web page console allows freeing the old pages from memory.

我不知道Chrome是否可能具有类似的行为,但可以肯定的是 措施,最好关闭其网络控制台以确保它不会 使页面保持活动状态.

I do not know if Chrome might have similar behavior, but for good measure, it is good to have its web console closed to ensure it is not keeping pages alive.

如果某人有一个可以发布的公共测试用例,则表明 有助于查明来源.

If someone has a public test case available that they can post, that would be helpful in pinpointing the source.

但实际上我的测试建议在解决Chrome浏览器时在firefox中仍然存在此问题.

But actually my test suggest that this problem still persist in fireFox while resolve for Google Chrome.

记住,经过长时间的努力,我得到了这个答案.

更新:我发现当您在Firefox中重新加载页面时,它获得的页面内存是原来的两倍.因此,这是Firefox的问题,与统一的webgl无关.

Update: I found that when you reload the page in firefox it get double the memory of page. So it is firefox issue, not related to unity webgl.

这篇关于Unity WebGL资产捆绑包内存未释放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆