About native memory usage:
- 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 - Activitywith one- Buttonand 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.
 
- Native memory can also be allocated from Java without the need of loading any native library with - ByteBuffer.allocateDirect(int).
 
- When you say that you're not loading any native library until next Activity,  if you're loading the library statically (withinstatic { }) 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).