Unity WebGL 资源包内存未释放

2024-01-12

我正在加载和缓存资产包统一使用以下函数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();
        }
        //}
    }

正如您所看到的,我正在删除第一个子项(我从资产包中获得的),然后调用 GC Collect 来强制垃圾收集器。但问题是,每当我卸载/销毁对象时,我的内存都不会释放。现在你会想我是如何测量内存的?我正在使用 WebGLMemoryStatshere https://github.com/kongregate/Unity-WebGL-Utilities/tree/master/Assets/Plugins/WebGLMemoryStats。 我在多次迭代 assetbundle 加载后得到了这个。

Edit:我现在正在使用 WebRequest 类下载 assetbundle (在这里找到 https://github.com/UnityCommunity/UnityLibrary/blob/master/Assets/Scripts/AssetBundles/AssetBundleLoader.cs)但仍然无法释放内存,有时会出现 aw snap 错误。

即使当我尝试一次又一次地加载空的 webgl 构建时,它也会增加内存堆,然后有时我会收到 aw snap 或内存错误和 chrome 崩溃。

正如您所看到的,初始负载约为 1.2 Mb,但是当我刷新页面并拍摄快照时,它的快照带来了增量内存。


请注意,您永远不会让它像您想象的那样完美运行。有一些实用程序可用于清理垃圾和卸载资源,但即使您遵循所有最佳实践,您仍然可能无法让 Unity 清理所有垃圾(它在后台执行大量操作,保留分配的内存,并且您不需要做太多工作)可以做点什么)。如果您好奇为什么会这样,我建议您阅读他们的文章堆碎片 https://docs.unity3d.com/Manual/BestPracticeUnderstandingPerformanceInUnity4-1.html?_ga=2.235425601.1547097256.1552318017-1747974858.1545148988以及他们的内存优化指南 https://unity3d.com/learn/tutorials/topics/performance-optimization/optimizing-garbage-collection-unity-games.


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

1) 避免使用WWW不惜一切代价上课。它产生的垃圾比它的价值多得多,并不总是能很好地清理,并且在最新版本的 Unity 中已过时。使用UnityWeb请求 https://docs.unity3d.com/Manual/UnityWebRequest-DownloadingAssetBundle.html下载捆绑包。

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

  1. 加载你需要的包
  2. 从该包中加载您需要的资源
  3. 等待一生all这些资产结束
  4. call bundle.Unload(true)

3) 拨打电话时要小心StopCoroutine(loadBundleRef); (if loadBundleRef is a Coroutine运行 Web 请求和捆绑加载逻辑的对象)。中断这些异步操作可能会导致内存问题。您应该采取一些措施来确保网络请求和捆绑包加载完全完成,或者在失败时抛出并让您的游戏恢复。不允许类似的事情StopCoroutine来打断他们。

4) System.GC.Collect();速度很慢并且垃圾收集无论如何都会定期发生。谨慎使用它,您可能还想打电话Resources.UnloadUnusedAssets https://docs.unity3d.com/ScriptReference/Resources.UnloadUnusedAssets.html在调用它之前。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Unity WebGL 资源包内存未释放 的相关文章

  • 在下载的同时从 UnityWebRequest 获取数据?

    我有这段代码可以进行 REST 调用 public IEnumerator GetCooroutine string route string finalURL URL route UnityWebRequest www UnityWebR
  • .Net Framework 4.8 和 .Net 5 之间的垃圾收集行为差异

    为了在已经发生很多次的地方检测潜在的内存泄漏 我使用了如下所示构建的测试 主要思想是拥有一个实例 不再引用它并让垃圾收集器收集它 我不想关注这是否是一种好的技术 在我的具体情况下它做得非常出色 但我想关注以下问题 下面的代码在 Net Fr
  • 如何在 Windows 中获取和设置系统音量

    我想使用 unity 和 c 将键盘点击时的操作系统音量设置为一定水平 例如我想将 Windows 音量 不是 unity 设置为 70 我该怎么做 void Update if Input GetKeyDown KeyCode A Set
  • C# 和 .Net 垃圾收集器性能

    我正在尝试用 C 和 NET 制作游戏 并且计划实现更新游戏世界中游戏对象的消息 这些消息将是 C 引用对象 我想要这种方法 因为如果我希望游戏是多人游戏 那么通过网络发送它们会更容易 但是如果我有很多消息 对于垃圾收集器来说不是压力很大吗
  • Unity3D 播放器在石头上行走

    大家好 我的玩家正在石头上行走并穿过石头 名为 Champ 的玩家有一个 Box Collider 而 Stone 有一个 Mesh Collider 玩家也有刚体 我尝试了我发现的一切 但没有任何帮助我解决我的问题 MovePlayer
  • 查找 Java 中的内存使用情况

    以下是我需要解决的场景 我想出了两种解决方案 我需要维护从数据库获取的数据的缓存 以便在 Swing GUI 上显示 每当我的 JVM 内存超过其分配内存的 70 时 我需要警告用户有关过度使用的情况 一旦 JVM 内存使用率超过 80 那
  • 与动态功能模块(应用程序包)一起安装时“存储空间不足”

    我有一个使用 Android App Bundle 的 DFM 动态安装的 Unity 项目 使用 Unity 2019 3 导出 并将其上传到 google play 进行内部测试 动态模块可以按需下载 但是当我运行 UnityActiv
  • 如何管理返回到 QML 的动态分配的 QObject 的生命周期?

    我有这个代码 QVariant componentFromCode QString code QQmlComponent component new QQmlComponent engine engine gt setObjectOwner
  • 如何在 Windows 7 中模拟内存不足的情况

    我有一个用 C 编写的应用程序 运行良好 但有时在现场会出现错误 我们认为这些错误是由于内存不足或与垃圾收集器的交互造成的 如果有人感兴趣 这里有描述 无法将 NHibernate Impl ExpandedQueryExpression
  • Hololens-无法连接到设备

    我意识到这个问题在其他地方被问过 但答案似乎直接针对 Hololens 和 PC 之间的配对过程 这是我的问题的一部分 我在 Unity 中制作了一个应用程序并导出到 Visual Studio 当我尝试在 Hololens 上运行它时 出
  • 在速度和距离不一致和/或有噪声的向量之间平滑地进行调整

    我正在可视化一级方程式赛车中提供的 GPS 数据 并尝试以动画方式显示它们在路径上的位置 Formula 1 API 提供矢量坐标和时间戳 但时间戳各不相同 它们的更新时间大约在 100 到 400 毫秒之间 timestamp x y z
  • GC.Add MemoryPressure() 如何知道要向哪个对象添加内存压力?

    我最近需要使用GC 添加内存压力 http msdn microsoft com en us library system gc addmemorypressure aspx令我感到奇怪的是 它不接受添加内存压力的对象作为参数 我认为因为它
  • V8 如何管理它的堆?

    我知道V8的垃圾收集在工作时 会从GC的root开始追踪 这样无法到达的对象就会被标记然后被清除 我的问题是GC是如何遍历那些对象的 必须有一个数据结构来存储所有可达或不可达的对象 位图 链接表 顺便说一句 JVM 也做同样的事情吗 艾伦秀
  • Java G1 GC 处理引用对象运行缓慢

    我已经在 J ava 上运行了计数器 它24小时工作 每秒点击通过100次左右 白天 GC 处理时间从 20 60 毫秒缓慢上升到 10000 60000 毫秒 然后下降到 20 60 毫秒 这种模式不时地重复 从 GC 日志中我发现 GC
  • 在 Unity 中使用 MRTK 和 Vuforia - 选择什么相机?

    我是 AR 新手 最近几天在 Unity 上设置了 MRTK 和 Vuforia 两者独立运行良好 现在我想在一个项目中使用两者 但问题是两者都有相机 MRTK 有自己的 MixedRealityCamera 和 Vuforia ARCam
  • RxJS - 我需要取消订阅吗

    如果我有这样的事情 class MyComponent constructor this interval Observbale interval 1000 const c new MyComponent const subscriptio
  • 为什么 Roslyn 中有这么多对象池的实现?

    The 对象池 http source roslyn codeplex com Microsoft CodeAnalysis ObjectPool 25601 cs 20b9a041fb2d5b00是 Roslyn C 编译器中使用的一种类
  • foreach 循环为 Unity 中的按钮赋值时出现问题

    我正在尝试在 Unity 中为我的游戏制作一个类似 Candy Crush 的地图 我正在尝试将所有按钮收集到一个数组中 然后设置其 onclick 属性 这样当我单击它们时 我就可以达到我想要的级别 我正在使用 Foreach 循环来实现
  • 在我的 Unity 应用程序中检测来电

    我试图让我的游戏在接到电话时暂停 我想知道我使用的任何函数是否可以做到这一点 我在我的源代码中使用了它们 但它们都不起作用 void OnApplicationPause bool paused if paused true if isPa
  • JVisualVM/JConsole 中的 System.gc() 与 GC 按钮

    我目前正在测试处理 XML 模式的概念验证原型 并围绕一个非常消耗内存的树自动机外部库 我已经获得了源代码 构建 我想绘制 真实峰值 堆 随着模式大小的增加 不同运行的内存消耗 使用的指标符合我的目的并且不会影响问题 或者至少是它的合理近似

随机推荐

  • 与 Firestore 异步

    我正在努力使ProgressBar旋转 同时数据来自Firestore正在加载到ListView 然后 加载后 ProgressBar应该消失 我就是这么做的 但在多线程方面我仍然是一个完全的零 这是内部类 我尝试使用异步 Progress
  • @Transactional 应该放在哪里?在接口规范或实现中? [复制]

    这个问题在这里已经有答案了 什么被认为是放置的最佳实践 Transactional注解 我应该注释接口方法还是实现 在我看来 这实际上完全取决于您的应用程序架构 这取决于您如何代理您的类 如果您的应用程序设置为proxy target cl
  • 如何在 Python 中向 YAML 文件添加注释

    我正在使用以下方式编写 YAML 文件https pypi python org pypi ruamel yaml https pypi python org pypi ruamel yaml 代码是这样的 import ruamel ya
  • cmake 和 libpthread

    我在跑RHEL 5 1并使用gcc 我怎么说cmake to add pthread编译和链接 Manuel 已经到了那里 您也可以添加编译器选项 如下所示 如果您有 CMake 3 1 0 这变得更加容易 https github com
  • 在 iOS 11 中使用大标题时调整栏按钮项目的位置

    我在 iOS 11 中使用大标题导航栏 但是当我添加一个栏按钮项目时 它看起来很奇怪 位于与原始标题导航栏相同的位置 我想当标题很大时将栏按钮项目向下移动 并在导航栏不再大时将其移回原来的位置 这样做的最好方法是什么 这是一张显示栏按钮项目
  • 我自己的自定义类中的扩展

    我正在阅读另一个SO问题 Swift do try catch 语法 https stackoverflow com questions 30720497 swift do try catch syntax 30720807 3072080
  • 重新排列 StoryBoard 中的选项卡栏控制器顺序

    在我的 iPhone 应用程序中 我有一个选项卡栏控制器 与 4 个不同的表视图控制器有 4 个关系 有没有办法以图形方式重新排列故事板中关系的顺序 我找不到办法做到这一点 我确信我一定错过了一些东西 在 4 5 中 添加控制器后保存故事板
  • 将按钮更优雅地放入表格列中

    这是一个 SSCCE 演示了如何放置Button进入TableView柱子 它有效 但几乎没有令人不快的行为 当表格行向下滚动时通过鼠标使用滚动条 新呈现的按钮不会立即显示 仅当释放并移动鼠标时才会显示它们 我认为还有另一种更优雅的方式来显
  • 来自 yahoo.finance.quotes 的同一查询有不同的结果。 (YQL)

    我正在使用 YQL 检索一些财务数据 我注意到最近我从 yahoo finance quotes 得到了相同查询的不同结果 例如 做了5次 LastTradeWithTime 9 09pm b 38 29 b LastTradeWithTi
  • 使用 dplyr 对每个组应用 ggplot 函数并为每个组设置标题

    我想在数据框中为每个组创建一个单独的图 并将该组包含在标题中 使用 iris 数据集 我可以在 R 和 ggplot 中执行此操作 plots1 lt lapply split iris iris Species function x gg
  • 如何使用StaggeredGridLayoutManager在recyclerview中实现无限滚动(分页)

    你好 我有一个recyclerview图像加载自firebase我想实现无限滚动 但我遇到的问题是StaggeredGridLayoutManager我必须使用它 但我无法替换它grid layout 注意 我看过关于这个主题的其他答案 但
  • JS 或 CSS 页面在 2 个完整页面之间滑动过渡

    我有两个html页面 Page1 html Page2 html 我想在两个页面之间滑动 我发现了很多插件和解决方案可以在两个 div 之间滑动或在容器内滑动 但我需要的是完整的页面更改 我发现了一些东西 http www fasw ws
  • 在 PowerShell 中比较数组变量

    我有这个脚本来比较两个文件夹 firstfolder Get ChildItem C firstfolder secondfolder Get ChildItem C firstfolder if firstfolder eq second
  • Azure CLI - 删除资源而不删除资源组

    目标是删除资源组中的所有资源 而不使用 azure CLI 删除它 通过阅读文档 我可以这样做 az resource delete g MyResourceGroup n MyVm 因此我认为我可以执行以下操作 az resource l
  • 使用 Jquery 调用 Angular 函数

    当文本框中有数据时如何调用角度函数 这是我的代码 html div div
  • #define GLUT_DISABLE_ATEXIT_HACK 是否有必要?由 小码哥发布于

    I use MinGW64 with eclipse编译一个FreeGLUT示例程序 我收到以下错误 11 55 58 Incremental Build of configuration Debug for project OpenGL
  • 删除底部的框阴影

    如果我不想在底部有框阴影 我应该将 CSS 更改为什么 我正在使用这个 但我有
  • 当 Rxjs 主题订阅/取消订阅时,如何接收通知

    我正在尝试使用 Rxjs 作为管理大型状态树中垃圾收集的方法 如何创建一个运算符 该运算符接受每次可观察的订阅者数量发生变化时触发的回调函数 多种方式 都涉及隐藏你的主题并为消费者提供包装的可观察对象 想知道何时有人订阅您的主题吗 cons
  • 将 csv 文件转换为字典列表

    我有一个 csv 文件 col1 col2 col3 1 2 3 4 5 6 我想从此 csv 创建一个字典列表 输出为 a col1 1 col2 2 col3 3 col1 4 col2 5 col3 6 我怎样才能做到这一点 Use
  • Unity WebGL 资源包内存未释放

    我正在加载和缓存资产包统一使用以下函数webgl IEnumerator DownloadAndCacheAB string assetName Wait for the Caching system to be ready while C