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