Android内存管理系统上的问题

景观

我的应用程序的目标是它必须在没有用户交互的情况下永远运行。但是它失败了很多次,可能与内存有关。根据Android文档,如果系统需要内存,则Android首先让用户通过onTrimMemory()警告。但是,如果Android系统需要更多内存,则抛出OOM(内存不足)异常,应用将崩溃。我的应用程序将Service与Activity一起使用,并且Service在运行时带有粘性通知。

private void startForegroundService(Context context, String text){
    Intent notificationIntent = new Intent(context, MainActivity.class);
    notificationIntent.setAction(Intent.ACTION_MAIN);
    notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER);
    notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
            | Intent.FLAG_ACTIVITY_SINGLE_TOP
            | Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);

    PendingIntent pendingIntent = PendingIntent.getActivity(context, 1,
            notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel channel = new NotificationChannel(
                NOTIFICATION_CHANNEL_ID,
                text,
                NotificationManager.IMPORTANCE_DEFAULT);
        ((NotificationManager) context.getSystemService(NOTIFICATION_SERVICE)).createNotificationChannel(channel);
        notificationBuilder = new Notification.Builder(context, NOTIFICATION_CHANNEL_ID);

    } else {
        notificationBuilder = new Notification.Builder(context);
    }

    notificationBuilder.setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle(getString(R.string.background_control))
            .setContentText(text)
            .setContentIntent(pendingIntent);

    startForeground(MAIN_NOTIFICATION_ID, notificationBuilder.build());
}

首先,我不了解的部分是与内存相关的事件未按顺序进行。例如,如果Android需要内存,则首先应按顺序(5、20、60,..)抛出onTrimMemory()级别;如果需要更多,则应抛出OOM。但是到目前为止,我所经历的不是顺序的,而是完全随机的。而且我的应用程序不会发生内存泄漏。我多次使用Android IDE Profiler进行了检查。而且某些测试应用程序不会出现内存问题。我想这可能意味着没有内存泄漏。

其次,我想知道如何准确估计内存。我现在正在使用Runtime.getRuntime()检查当前内存。不只是App的堆内存,而且还有系统。当发生崩溃时,我会记录日志,但内存已足够。下面的代码用于记录事件发生的时间。

@Override
public void onTrimMemory(int level) {
    super.onTrimMemory(level);
    Runtime runtime = Runtime.getRuntime();
    long totalMem = runtime.totalMemory();
    long freeMem = runtime.freeMemory();
    final double usedMemInMB = (double) (totalMem - freeMem) / 1048576;

    LogManager.addLog(LogManager.WARNING_TAG,
            "onTrimMemory Level(" + level + "), Free/ Used/ Total/ Avail: "
                    + String.format("%5.2f", (freeMem / 1024.0 / 1024.0)) + "/ "
                    + String.format("%5.2f", usedMemInMB) + "/ "
                    + String.format("%5.2f", (totalMem / 1024.0 / 1024.0)) + "/ "
                    + String.format("%7.2f", (getAvailableMemory() / 1024.0 / 1024.0)) + "MB"
    );
}

private long getAvailableMemory() {
    ActivityManager activityManager = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
    ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
    activityManager.getMemoryInfo(memoryInfo);

    return memoryInfo.availMem;
}

所以我不明白为什么Android会在没有警告的情况下抛出onTrimMemory()或OOM甚至杀死我的App。

景观

我的应用程序中只有一个内存泄漏已解决。我建议使用Android Studio的事件探查器,如果有人遇到此问题,请查找泄漏的位置。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

UIImageJPEGRepresentation上可能的内存问题

来自分类Dev

Android应用程序中的内存管理

来自分类Dev

在库管理系统上使用多线程

来自分类Dev

Android Endless列表内存管理

来自分类Dev

需要Android NDK NativeActivity内存管理?

来自分类Dev

Java可以系统出局导致内存不足的问题

来自分类Dev

操作系统是否管理内存映射文件?

来自分类Dev

CesiumJS内存管理问题

来自分类Dev

管理内存泄漏C ++的问题

来自分类Dev

内存问题,如何管理退出的Docker容器?

来自分类Dev

通过Android上的文件管理器非法访问文件系统

来自分类Dev

Android内存管理粒度-活动还是流程?

来自分类Dev

Android UI图像内存问题

来自分类Dev

共享内存系统VC中的矩阵问题

来自分类Dev

JPA内存管理问题

来自分类Dev

文件存在内存管理问题

来自分类Dev

内存不足android问题

来自分类Dev

无法解决操作系统中的内存管理问题

来自分类Dev

Android ImageView内存管理

来自分类Dev

Android应用程序中的内存管理

来自分类Dev

带有JNI的Android不良的管理内存

来自分类Dev

C ++内存管理在局部变量上的内存分配

来自分类Dev

需要Android NDK NativeActivity内存管理?

来自分类Dev

c中的操作系统内存管理分页方案

来自分类Dev

Android内存管理问题

来自分类Dev

Android UI图像内存问题

来自分类Dev

Linux内存管理系统中的内存立即可用

来自分类Dev

C++中的内存管理问题

来自分类Dev

如何在android recycleview上管理项目过多的内存