我有一个MonoTouch应用程序,每1/12秒加载一个帧。我正在使用UIkit,而不是opengl。我在视图中有一个UIImage
,并且有一个backgroundtask我正在加载图像。
一切都还可以,但是,一分钟后(或多或少),应用程序停止,跟踪器给我“低内存压力”
它在模拟器中工作正常,没有任何问题。我正在查看分析器,似乎内存已经处理好,但是当我在iPad上试用它时:....(
我使用image.Dispose()
释放内存。我在内存中有2个图像,显示其中一个然后释放旧图像。这种行为没问题,因为我在Windows Phone上具有相同的逻辑,并且工作正常。
我已经尝试不使用backgroundTask,并直接从主线程加载图像。它给了我更多时间!如果我使用backgroundTask,应用程序运行30秒然后退出。如果我不使用backgroundTask,它会持续1分钟。
我不知道该怎么办!!!!有人可以帮帮我吗?
感谢!!!
Texture2D.FromStream它只是UIImage.FromFile的包装器
这是后台工作人员:
void LoadTextureInBackground()
{
if (currentMovie == null) return;
DateTime timeOnstart = DateTime.Now;
// Mantenemos 2 texturas en memoria para no cargar sobre el mismo objeto texture.
string fileName = currentMovie.GetFileName();
if (lastFileName == fileName) return;
textureLoaded[currentTexture] = Texture2D.FromStream(Device.GraphicsDevice, fileName);
texture = textureLoaded[currentTexture];
currentTexture = 1 - currentTexture;
lastFileName = fileName;
GC.Collect();
System.Threading.Thread.Sleep(50);
}
这是绘制方法:
/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
public void Draw(TimeSpan totalTime,TimeSpan elapsedTime)
{
if(currentMovie==null) return;
// Mantenemos 2 texturas en memoria para no cargar sobre el mismo objeto texture.
if (texture == null) return;
int newWidth = (int)(texture.Width*RenderSize);
int newHeight = (int)(texture.Height*RenderSize);
Texture2D drawTexture = texture;
// Al cargar usando Texture2D.FromStream, la textura NO lleva elAlpha premultiplicado
//Device.SpriteBatch.Draw(drawTexture, destination, Color.White);
if(CultTravel.AppDelegate.ImagePng.Image!=drawTexture.Texture)
{
AppDelegate.ImagePng.Image=drawTexture.Texture;
AppDelegate.ImagePng.Frame=new System.Drawing.RectangleF(0,480-newHeight,ImagePng.Image.CGImage.Width,newHeight);
// Si la textura que tengo cargada y lista para mostrar es diferente a la que mostraba, libero la antigua
if (lastTextureDraw!=null && lastTextureDraw != texture)
{
lastTextureDraw.Dispose();
}
lastTextureDraw = texture;
}
注意: 我刚刚解决了这个问题,但是我必须禁用后台工作程序,在Draw方法中添加加载代码并在主线程中添加GC.Collect:
if (lastTextureDraw!=null && lastTextureDraw != texture)
{
lastTextureDraw.Dispose();
// I MUST ADD THIS TO WORK AND DISABLE THE BACKGROUND TASK!!
GC.Collect();
}
答案 0 :(得分:1)
我刚刚解决了这个问题,但我必须禁用后台工作程序,在Draw方法中添加加载代码并在主线程中添加GC.Collect:
if (lastTextureDraw!=null && lastTextureDraw != texture)
{
lastTextureDraw.Dispose();
// I MUST ADD THIS TO WORK AND DISABLE THE BACKGROUND TASK!!
GC.Collect();
}
所以,使用线程时出了点问题......
答案 1 :(得分:0)
它在模拟器中工作正常,没有任何问题。
这不是模拟器,而是模拟器。因此,它不会尝试模仿特定设备,包括它的内存限制。 IOW iOS模拟器可以访问更多内存而不是iPad(第一代256MB,第二代512MB,第三代1GB)。
我正在查看分析器
哪一个? MonoDevelop的HeapShot还是Apple的乐器?
我使用image.Dipose()来释放内存。
这是一个好主意 - 但 只能在管理方面工作。例如。一些API将缓存图像,因为它不是托管内存(它本地分配的内存),因此内存不会显示在HeapShot上。您将有更好的机会使用Apple的仪器跟踪此事。
它可能也是其他东西......就像@ Jonathan.Peppers问的那样,看到你如何加载图像可以帮助我们看出错误。