rusty8521
rusty8521

Reputation: 41

Xamarin android memory consumption grows infinitely after usage hits a certain threshold

I have an Xamarin android application and it seems as though when the memory usage of the app hits a certain threshold 140mb to 160mb the app will rapidly start taking up more memory as if in an infinite loop. I can see in the debugger output that the garbage collector keeps repeatedly trying to free memory but it doesn't seem to work. The memory usage will grow seemingly without bound. I watched it rise to well over 500mb of memory before I decide kill the app. I NEVER get an out of memory exception which is really weird. From what I can tell there is no specific piece of code that this happens on I can be in various screens and the same thing will occur. I have tested on multiple devices so I know its not just a problem with my device. I would attempt to show some code but I don't have any culprits.

Among the components used in my app that could maybe cause an issue are ReshSharp clients, .net Webclients, use of bitmaps, a TabHost with 3 tabs, location manager, and taking of photos through the camera. I'm stumped on this one any help is greatly appreciated.

EDIT: It's possible that I have narrowed down where one of the problems might be. I have a camera activity inside of a tabhost for taking photos, I have a on photo taken method that gets called after snapping a picture, after taking several photos the problem arises. Here is the method

    public void OnPictureTaken(byte[] data, global::Android.Hardware.Camera c)
    {
        GC.Collect();
        Bitmap b = BitmapExtensions.DecodeBitmapFromArray(data, WIDTH, HEIGHT);

        Matrix matrix = new Matrix();
        matrix.SetRotate(RotationDegrees, WIDTH / 2f, HEIGHT / 2f);

        var bitmapScalled = Bitmap.CreateBitmap(b, 0, 0, WIDTH, HEIGHT, matrix, true);

        var d = global::Android.OS.Environment.ExternalStorageDirectory.Path + "/MyApp/";
        if (!Directory.Exists(d))
            Directory.CreateDirectory(d);

        file = d + Guid.NewGuid().ToString() + ".jpg";

        System.IO.StreamWriter sw = new System.IO.StreamWriter(file);
        bitmapScalled.Compress(Bitmap.CompressFormat.Jpeg, 70, sw.BaseStream);
        sw.Close();

        global::Android.Locations.Location location = CameraLocationManager.GetLastKnownLocation(CameraLocationManager.GetBestProvider(new Criteria() { Accuracy = Accuracy.Fine }, true));

        Intent intent = new Intent(this, typeof(EditPhotoActivity));
        intent.PutExtra("LastKnownLocation", JsonConvert.SerializeObject(LastKnownLocation));
        intent.PutExtra("Filename", file);
        //StartActivity(intent);
        StartCamera(); // restart camera preview
        b.Recycle();
        b = null;
        sw.Dispose();
        bitmapScalled.Dispose();
        bitmapScalled = null;
        // clean up
        GC.Collect();
    }

Upvotes: 4

Views: 1191

Answers (1)

baraka
baraka

Reputation: 806

Although Xamarin profiler is still in preview it helped me a lot tracking down memory issues we had in our application. Reading your last comment i can confirm Xamarin Insights (v1.10.1) has a significant huge memory signature (and might even leak). After we removed it from our code - the app was behaving super fast!

Bottom line - use the profiler to identify memory issues and if you have Xamarin Insights used in your app - i suggest to remove it until further notice.

Upvotes: 3

Related Questions