Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unity3d iOS上的资产绑定:内存始终增加,导致崩溃_Unity3d_Assetbundle - Fatal编程技术网

Unity3d iOS上的资产绑定:内存始终增加,导致崩溃

Unity3d iOS上的资产绑定:内存始终增加,导致崩溃,unity3d,assetbundle,Unity3d,Assetbundle,我们的资产包存储在Amazon S3存储桶中。当游戏开始时,它会使用WWW.LoadFromCacheOrDownload确定需要下载新版本的捆绑包 我们遇到的问题是,iOS报告为我们的应用程序分配的内存不断增加,但Unity报告它使用的内存(通过探查器)始终保持不变。我们有足够的捆绑包,当它下载完我们需要的所有东西时,它总是会收到来自iOS的内存警告,不久之后,由于内存压力,我们将关闭它 我们已经有了通用的解决方案:在WWW完成后卸载assetbundle,使用assetbundle.unlo

我们的资产包存储在Amazon S3存储桶中。当游戏开始时,它会使用WWW.LoadFromCacheOrDownload确定需要下载新版本的捆绑包

我们遇到的问题是,iOS报告为我们的应用程序分配的内存不断增加,但Unity报告它使用的内存(通过探查器)始终保持不变。我们有足够的捆绑包,当它下载完我们需要的所有东西时,它总是会收到来自iOS的内存警告,不久之后,由于内存压力,我们将关闭它

我们已经有了通用的解决方案:在WWW完成后卸载assetbundle,使用assetbundle.unload(),调用Resources.UnloadUnusedAssets(),并在WWW上调用Dispose()。这些都不能解决问题

代码如下:

    private IEnumerator DownloadBundle(DownloadQueueEntry entry, DownloadFinishedCallback callback)
    {
        while (!entry.finished)
        {
            // grab bundle off S3
            string url = string.Format(BUNDLE_URL_FORMAT, entry.directory, entry.assetName);

            WWW www = WWW.LoadFromCacheOrDownload(url, entry.version);

            yield return www;

            if (string.IsNullOrEmpty(www.error))
            {
                Debug.Log("[BundleDownloader] Download Completed " + entry.assetName);

                entry.finished = true;
                entry.downloading = false;
                www.assetBundle.Unload (true);
                Resources.UnloadUnusedAssets ();
            }
            else
            {
                // usually timed out resolving host, just try again for now
                Debug.LogError("[BundleDownloader] Download failed: " + url + " Error: " + www.error);
            }

            www.Dispose();
            www = null;
        }
        if(callback != null)
        {
            callback ();
        }

    }
--编辑--

下面的链接中有一个显示内存使用量增加的屏幕截图。内存使用一直如此,直到消耗了大约150MB。这都是在一个场景中,只有一个游戏对象的初始化脚本(没有艺术或任何东西)


正如Unity文档所建议的,您确实应该将您对WWW对象/缓存例程的使用封装在一个“using”语句块中

using System;
using UnityEngine;
using System.Collections;

public class CachingLoadExample : MonoBehaviour {
public string BundleURL;
public string AssetName;
public int version;

void Start() {
    StartCoroutine (DownloadAndCache());
}

IEnumerator DownloadAndCache (){
    // 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 (BundleURL, version)){
        yield return www;
        if (www.error != null)
            throw new Exception("WWW download had an error:" + www.error);
        AssetBundle bundle = www.assetBundle;
        if (AssetName == "")
            Instantiate(bundle.mainAsset);
        else
            Instantiate(bundle.Load(AssetName));
                // Unload the AssetBundles compressed contents to conserve memory
                bundle.Unload(false);

    } // memory is freed from the web stream (www.Dispose() gets called implicitly)
}
}
“using”语句是一种C#特性,可确保“Dispose()”方法正常工作(在许多情况下,会自动调用)

如MS文件所述:

“[使用]提供了一种方便的语法,确保正确使用IDisposable对象。”


我猜您的内存泄漏是由于这些功能未按预期运行(可能是由于配置不当,不确定)。

我们的应用程序也遇到了类似问题。我们从WWW加载了很多纹理,注意到iOS是唯一一个内存泄漏的平台。我们最终在这里找到了解决方案。基本上,unity 4.3中存在一个已知的问题,即从www调用中泄漏数据。这应该在unity 4.5中固定。同时,您可以按照Alexey的建议修改generate xcode项目中的代码或更新到4.5:

4.5将得到修复。 基本上,您需要: 寻找 外部“C”void unitydestroywwww连接(void*连接) 在WWWConnection.mm中

[delegate.connection cancel];
delegate.connection=nil;

[delegate.data release];// 我在iPad上下载AssetBundle时也遇到过类似的问题。然而,就我而言

  • 我正在从服务器下载assetbundle(不使用缓存)并稍后加载它。在一个资产包中,如果资产包中的图像超过100个,比如说200个,那么它会提升内存
  • 这不是UNITYDESTROYWWW连接或“使用”问题。我正在下载60MB的资产包(在生成资产包时使用最佳压缩),下载时使用了大约450MB
  • 我检查了仪器的结果,在下载资产包时看到了成吨的小malloc
我的猜测-不确定:Unity在继续下载时从资产包中提取信息,这会导致内存错误。它首先获取标题信息,并了解它是unity3d对象,因为它使用它准备的www类下载

我的解决办法是:

  • 压缩assetbundle并将服务器作为zip
  • 在iPad上下载资产包zip并提取(使用SharpZipLib)

将尝试。我不知道它是否存在相同的问题,但当我第二次尝试从web加载相同的纹理时,它会立即加载,这意味着它存储在某个地方。
[delegate.connection cancel]; 
delegate.connection = nil;
[delegate.data release]; // <-- ADD THIS
[delegate release];