簡體   English   中英

內存壓力在MonoTouch中加載一堆PNG圖像

[英]Memory pressure loading a bunch of PNG images in MonoTouch

我有一個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();
        }

我剛剛解決了這個問題,但是我必須禁用后台工作程序,在Draw方法中添加加載代碼,並在主線程中添加GC.Collect:

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

因此,使用線程時出了點問題。

它在仿真器中工作正常,沒有問題。

這不是模擬器,而是模擬器 因此,它不會嘗試模仿特定的設備,包括它的內存限制。 督察了iOS模擬器訪問比你的iPad(第一代256MB,第二代的512MB,第三代1GB) 更多的內存。

我在看探查器

哪一個 ? MonoDevelop的HeapShot還是Apple的Instruments?

我使用image.Dipose()釋放了內存。

這是一個好主意-但它只能在管理方面的工作。 例如,某些API將緩存圖像,該內存將不會在HeapShot上顯示,因為它不是托管內存(它是本機分配的內存)。 您將有更好的機會使用Apple的Instruments進行跟蹤。

也可能是其他東西...這意味着,例如@ Jonathan.Peppers問,了解您如何加載圖像可以幫助我們了解問題所在。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM