2

我有一个 MonoTouch 应用程序,它每 1/12 秒加载一个帧。我正在使用 UIkit,而不是 opengl。我有一个UIImage进入视图,并使用背景任务加载图像。

一切正常,但一分钟后(或多或少),应用程序停止,跟踪器给我一个“低内存压力”

它在模拟器中运行良好,没有问题。我正在查看分析器,似乎内存已被处理,但是当我在 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();
        }
4

2 回答 2

1

我刚刚解决了这个问题,但是我必须禁用后台工作程序,在 Draw 方法中添加加载代码并在主线程中添加 GC.Collect:

   if (lastTextureDraw!=null && lastTextureDraw != texture)
    {
        lastTextureDraw.Dispose();
        // I MUST ADD THIS TO WORK AND DISABLE THE BACKGROUND TASK!!
        GC.Collect();
    }

因此,在使用线程时出现了问题......

于 2012-04-24T18:18:32.757 回答
0

它在模拟器中运行良好,没有问题。

这不是模拟器,而是模拟器。因此,它不会尝试模仿特定设备,包括它的内存限制。IOW iOS 模拟器可以访问比 iPad更多的内存(第一代 256MB,第二代 512MB,第三代 1GB)。

我在看分析器

哪一个 ?MonoDevelop 的 HeapShot 还是 Apple 的 Instruments?

我使用 image.Dipose() 释放内存。

这是一个好主意 - 但它只能在托管方面起作用。例如,某些 API 将缓存图像,该内存不会显示在 HeapShot 上,因为它不是托管内存(它是本机分配的内存)。您将有更好的机会使用 Apple 的 Instruments 进行跟踪。

它也可能是别的东西......这意味着,就像@Jonathan.Peppers 所问的那样,看看你如何加载图像可以帮助我们找出问题所在。

于 2012-04-23T14:05:27.127 回答