2

アセットバンドルは Amazon S3 バケットに保存されています。ゲームが開始されると、WWW.LoadFromCacheOrDownload を使用して、新しいバージョンをダウンロードする必要があるバンドルが決定されます。

私たちが直面している問題は、iOS がアプリに割り当てたメモリのレポートが増え続けていることですが、Unity が (プロファイラーを通じて) 使用しているとレポートするメモリは常に同じままです。必要なものすべてのダウンロードが完了するまでに十分な数のバンドルがあり、常に iOS からメモリ警告を受け取り、すぐにメモリ不足のためにシャットダウンされます。

一般的な解決策としては、WWW の終了後にアセットバンドルをアンロードする、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 になるまでこのように進みます。これはすべて、init スクリプト用の GameObject しかない (アートも何もない) シーンの中にあります。

https://www.dropbox.com/s/3b6skexz6xhug5g/Screenshot%202014-03-28%2014.54.26.png

4

3 に答える 3

1

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」ステートメントは、「Dispose()」メソッドが正しく機能することを保証する C# の機能です (多くの場合、自動的に呼び出されます)。

MS のドキュメントに記載されているとおり: http://msdn.microsoft.com/en-us/library/yh598w02.aspx

「[using] IDisposable オブジェクトの正しい使用を保証する便利な構文を提供します。」

あなたのメモリリークは、これらの機能が意図したとおりに実行されていないことが原因だと思います(おそらく不適切な構成が原因で、わかりません)。

于 2014-04-10T17:07:28.983 に答える
1

iPad で AssetBundle をダウンロードする際にも同様の問題がありました。ただし、私の場合は。

  • サーバーからアセットバンドルを(キャッシュを使用せずに)ダウンロードし、後でロードしていました。1 つのアセット バンドルで、アセット バンドルに 100 を超える画像、または 200 などの画像がある場合、メモリをブーストします。
  • これは UnityDestroyWWWConnection や「使用」の問題ではありません。私は 60MB のアセット バンドルをダウンロードしていました (アセット バンドルの生成に最適な圧縮を使用)。ダウンロード中に約 450MB を使用します。
  • インストゥルメントから結果を確認したところ、アセット バンドルのダウンロード中に多数の小さな malloc が表示されました。機器のスクリーンショットはこちらから確認できます。

私の推測 - よくわかりません: Unity は、ダウンロードの続行中にアセット バンドルから情報を抽出するため、メモリにエラーが発生します。まずヘッダー情報を取得し、unity3d オブジェクトであることがわかり、www クラスでダウンロードするのでWWW アセット バンドルの準備をします。

私の解決策は次のとおりです。

  • アセットバンドルを圧縮し、サーバーを zip として配置します。
  • アセット バンドルの zip をダウンロードして iPad で解凍する (SharpZipLib を使用)
于 2014-09-22T14:17:09.610 に答える
0

アプリで同様の問題が発生しました。WWW から多くのテクスチャを読み込んでいたところ、iOS が唯一のプラットフォームであり、そこからメモリ リークが発生していることに気付きました。私たちは最終的にhttp://forum.unity3d.com/threads/www-memory-leak-ios.227753/で解決策を見つけました。基本的に、ユニティ 4.3 には、www 呼び出しからデータが漏洩するという既知の問題があります。これは Unity 4.5 で修正する必要があります。それまでの間、Alexey の提案に従って、generate xcode プロジェクトのコードを変更するか、4.5 に更新することができます。

4.5には修正が含まれます。基本的に必要なもの: WWWConnection.mm で extern "C" void UnityDestroyWWWConnection(void* connection) を検索します

[delegate.connection cancel]; 
delegate.connection = nil;
[delegate.data release]; // <-- ADD THIS
[delegate release];
于 2014-08-08T18:16:59.647 に答える