Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why "Code" and "Native" sections in Memory Profiler use too much memory and how can I reduce it?

My app uses 75MB memory when the user opens it for the first time.

I have used Android Profiler Tool from Android Studio to examine memory usage of my Android app. When the main screen opens up, the app starts using 75MB memory even though the main activity does not create any object that needs too much memory. No bitmaps or any big arrays etc.

40MB is from "Code" section, and 19MB is from "Native" which we do not load any native library in this Activity. We do load after user opens another Activity though. I am trying to reduce the memory usage and I was wondering how can I reduce from "Code" and "Native" section.

Screenshot from Android Profiler

enter image description here

like image 316
cezmi sakar Avatar asked Mar 01 '18 09:03

cezmi sakar


1 Answers

About native memory usage:

  1. Android framework can make use of native memory even if you have 0 native code in your app, see "native" here for reference. For instance, I just tried to make a sample project, just one Activity with one Button and native memory usage is 18mb, if I trigger a garbage collection it drops to 8mb though. In order to manually trigger a garbage collection in Android Studio, you can click on the "trash bin" icon on the top left of the memory profiler window. Don't be shy with that button, I usually have to press it many times in a row to see memory usage drop.

  2. Native memory can also be allocated from Java without the need of loading any native library with ByteBuffer.allocateDirect(int).

  3. When you say that you're not loading any native library until next Activity, if you're loading the library statically (within static { }) you are not guaranteed that the library will be actually loaded when the second Activity starts. It could very well happen that it gets loaded before. If you want to check when the library actually gets loaded you could try to add this method to your C code, it should be called when your library is loaded. It's super dirty but, hey, it works. You might log something instead of crashing.

__attribute__((constructor)) void init(void) { int a = *(int *) ((void *) 0); }

About code memory usage, you should reduce your code :)

If you're not doing it already, set minifyEnabled to true in your build type, assuming you're inspecting memory usage with debug build:

    ...
    buildTypes {
        debug {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    ...

Also, turn off instant run (see "note" here).

like image 111
lelloman Avatar answered Oct 13 '22 01:10

lelloman