Search Unity

Question How to get Available memory in user's mobile using Unity App.

Discussion in 'Android' started by JayakumarSivasankar, May 4, 2021.

  1. JayakumarSivasankar

    JayakumarSivasankar

    Joined:
    Jan 21, 2021
    Posts:
    3
    Hi ,

    I m working with a Unity AR mobile app and since AR camera uses high device memory, I need to ensure that User's mobile is having enough memory.

    Thus, I have to find a way to get the available memory in User's mobile and to display it inside a alert message when user is running out of memory.

    Could you please help me to fetch the available memory from User's mobile?
    or a way to alert the user when their mobile is are running out of memory.

    Note I tried all the following , but still no luck:

    1. Application.lowmemory
    2. PerformanceCounter
    3. StatFS
    4.DriveInfo
     
    Last edited: May 4, 2021
  2. eugeneloza

    eugeneloza

    Joined:
    Dec 3, 2019
    Posts:
    24
    Note, that in modern OS (I believe Android included) the "available memory" is a rather vague term, as they make use of swap files to extend the memory practically indefinitely at the cost of performance. However,

    Is exactly what is made for your usecase. Why it doesn't work for you? Note that it requires a proper capitalization: "Application.lowMemory" - "M" is capital.

    Hmm... are you sure about that? I'm working on a quite a resource-heavy AR app (including a memory-hungry map plugin) and we've never ever hit memory limits - on any AR-capable phone. On the contrary we did have memory issues with texture-heavy scenes in another non-AR project.

    What is the problem you are encountering? What are the symptoms?
     
  3. JayakumarSivasankar

    JayakumarSivasankar

    Joined:
    Jan 21, 2021
    Posts:
    3
    Hi eugeneloza ,

    Thanks for the detailed response.

    The document states that "This event occurs when your app receives a low-memory notification from the device it is running on".

    Hence , I thought of using this concept to alert the user .

    I first tested the code sample provided on the documentation and added a small logic that would activate a gameobject upon lowmemory. (Below the C# Script).

    But , Its not working as expected. Instead it leads to AppCrash.

    Could you please help with this?

    *****************************************************************************************************************************
    //Below script referred from the documentation with extra logic to activate a gameobject upon lowMemory alert

    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;

    class SN1 : MonoBehaviour
    {
    List<Texture2D> _textures;
    public GameObject gameobj;


    private void Start()
    {
    _textures = new List<Texture2D>();
    Application.lowMemory += OnLowMemory;
    }

    private void Update()
    {
    // allocate textures until we run out of memory
    _textures.Add(new Texture2D(256, 256));
    }

    private void OnLowMemory()
    {
    // release all cached textures
    _textures = new List<Texture2D>();
    Resources.UnloadUnusedAssets();
    gameobj.SetActive(true);
    }
    }

    //End ***********************************************************************************************

    Regards,
    Jayakumar
     
  4. eugeneloza

    eugeneloza

    Joined:
    Dec 3, 2019
    Posts:
    24
    Unfortunately I don't think I can offer much help here further.

    Try to log `GC.GetTotalMemory(false)`

    And maybe do a `GC.Collect()` somewhere inside `OnLowMemory`.
     
  5. TreyK-47

    TreyK-47

    Unity Technologies

    Joined:
    Oct 22, 2019
    Posts:
    1,822
    I think you might find more help on one of our Mobile forums, so I'll move this thread there.
     
  6. cdr9042

    cdr9042

    Joined:
    Apr 22, 2018
    Posts:
    173
    I did it on Android by making an AAR plugin in Android Studio

    code:
    Code (CSharp):
    1. package com.a.memoryinfo;
    2. import static android.content.Context.ACTIVITY_SERVICE;
    3. import android.os.Bundle;
    4. import android.util.Log;
    5. import android.app.ActivityManager;
    6. import androidx.appcompat.app.AppCompatActivity;
    7. import android.app.ActivityManager.MemoryInfo;
    8. import android.app.Activity;
    9.  
    10. public class MemoryInfoChecker {
    11.  
    12.     private static Activity UnityPlayer;
    13.     private static ActivityManager activityManager;
    14.     private static  ActivityManager.MemoryInfo memoryInfo;
    15.  
    16.     public static void receiveUnityActivity(Activity _activity){
    17.         UnityPlayer = _activity;
    18.         activityManager = (ActivityManager) UnityPlayer.getSystemService(ACTIVITY_SERVICE);
    19.         memoryInfo = new ActivityManager.MemoryInfo();
    20.     }
    21.  
    22.     public double getAvailableMemory() {
    23.         activityManager.getMemoryInfo(memoryInfo);
    24.         return memoryInfo.availMem;
    25.     }
    26.  
    27.     public double getTotalMemory() {
    28.         activityManager.getMemoryInfo(memoryInfo);
    29.         return  memoryInfo.totalMem;
    30.     }
    31. }
    32.  
    Put the AAR in Unity and then use this code to access memory information

    Code (CSharp):
    1. private AndroidJavaClass unityClass;
    2.     private AndroidJavaObject unityActivity;
    3.     private static AndroidJavaObject _pluginInstance;
    4.  
    5. //initialize
    6.     unityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
    7.     unityActivity = unityClass.GetStatic<AndroidJavaObject>("currentActivity");
    8.     _pluginInstance = new AndroidJavaObject("com.a.memoryinfo.MemoryInfoChecker");
    9.     _pluginInstance.CallStatic("receiveUnityActivity", unityActivity);
    10.  
    11. public static double getAvailableMemory()
    12.     {
    13.         return _pluginInstance.Call<double>("getAvailableMemory");
    14.     }
    15.  
    16.  
     
  7. VirZOOM

    VirZOOM

    Joined:
    Mar 16, 2017
    Posts:
    6
    We find available memory useful too! Here's a way to get it without a plugin

    Code (CSharp):
    1.       var player = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
    2.       var activity = player.GetStatic<AndroidJavaObject>("currentActivity");
    3.       var manager = activity.Call<AndroidJavaObject>("getSystemService", "activity");
    4.       AndroidJavaObject mi = new AndroidJavaObject("android.app.ActivityManager$MemoryInfo");
    5.       manager.Call("getMemoryInfo", mi);
    6.       var avail = mi.Get<long>("availMem") / 1024 / 1024;
     
    Last edited: Dec 13, 2023