【问题标题】:Why "Code" and "Native" sections in Memory Profiler use too much memory and how can I reduce it?为什么 Memory Profiler 中的“代码”和“本机”部分使用太多内存,我该如何减少它?
【发布时间】:2018-08-09 08:26:04
【问题描述】:

当用户第一次打开我的应用时,它使用了 75MB 内存。

我使用 Android Studio 中的 Android Profiler Tool 来检查我的 Android 应用的内存使用情况。当主屏幕打开时,应用程序开始使用 75MB 内存,即使主 Activity 没有创建任何需要太多内存的对象。没有位图或任何大数组等。

40MB 来自“代码”部分,19MB 来自“Native”,我们不会在此 Activity 中加载任何原生库。我们会在用户打开另一个 Activity 后加载。 我正在尝试减少内存使用量,我想知道如何从“代码”和“本机”部分减少。

Android Profiler 的屏幕截图

【问题讨论】:

  • 你试过使用 Proguard 吗?
  • 是的,我正在使用 ProGuard
  • 希望你检查过this
  • 即使您的应用程序中没有使用 C++,您也可能会看到这里使用了一些本机内存,因为 Android 框架使用本机内存来代表您处理各种任务,例如在处理图像资源和其他图形——即使您编写的代码是用 Java 或 Kotlin 编写的。来自developer.android.com/studio/profile/memory-profiler.html
  • 我已经看过了,它没有提供太多信息。

标签: android memory android-profiler


【解决方案1】:

关于native内存使用情况:

  1. 即使您的应用程序中有 0 个本机代码,Android 框架也可以使用本机内存,请参阅“本机”here 以供参考。例如,我只是尝试制作一个示例项目,只有一个 Activity 和一个 Button,本机内存使用量为 18mb,如果我触发垃圾收集,它会降至 8mb。为了在 Android Studio 中手动触发垃圾回收,您可以单击内存分析器窗口左上方的“垃圾箱”图标。不要害羞那个按钮,我通常要连续按很多次才能看到内存使用率下降。

  2. 本机内存也可以从 Java 分配,而无需使用 ByteBuffer.allocateDirect(int) 加载任何本机库。

  3. 当您说直到下一个Activity 之前不会加载任何本机库时,如果您静态加载库(在static { } 内),则不能保证在第二个活动时实际加载库开始。它很可能会在之前加载。如果您想检查库何时实际加载,您可以尝试将此方法添加到您的 C 代码中,它应该在加载库时调用。它非常脏,但是,嘿,它有效。您可能会记录一些内容而不是崩溃。

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

关于code的内存使用,你应该减少你的代码:)

如果您还没有这样做,请在您的构建类型中将 minifyEnabled 设置为 true,假设您正在使用调试构建检查内存使用情况:

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

另外,关闭即时运行(参见“注释”here)。

【讨论】:

  • Java + Code + Stack 占用了可用堆吗? stackoverflow.com/a/9428660/2075875
  • 我不知道,但我会感到惊讶,但据我所知,堆、堆栈和代码是不同的内存空间。当您创建对象时,它们被分配在堆中(并最终被垃圾回收),当虚拟机加载类时代码应该发生变化,并且堆栈在运行时用于分配执行代码所需的内存。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-19
  • 2015-05-31
  • 2011-10-24
  • 2012-02-06
相关资源
最近更新 更多